home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-02-21 | 866.2 KB | 10,952 lines |
- //JOBNAME JOB ACCOUNT,'NAME'
- //*------------------------------------------------------------------*/
- //* */
- //* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- //* */
- //* This software is provided on an "AS IS" basis. All warranties, */
- //* including the implied warranties of merchantability and fitness, */
- //* are expressly denied. */
- //* */
- //* Provided this copyright notice is included, this software may */
- //* be freely distributed and not offered for sale. */
- //* */
- //* Changes or modifications may be made and used only by the maker */
- //* of same, and not further distributed. Such modifications should */
- //* be mailed to the author for consideration for addition to the */
- //* software and incorporation in subsequent releases. */
- //* */
- //*------------------------------------------------------------------*/
- //*
- //* MVS GOPHER client
- //*
- //* Author: Steve Bacher <seb1525@mvs.draper.com>
- //*
- //* Date: July, 1992
- //*
- //*--------------------------------------------------------------------
- //*
- //* This job creates the GOPHER distribution libraries (PDS's).
- //*
- //* Run this JCL to create the PDS's, after customizing to suit.
- //* (Obviously, put in a good JOB statement first.)
- //* To customize the JCL, change the defaults on the //GGLOAD PROC
- //* statement to your liking, particularly the PREFIX default.
- //* You might also want to change the final qualifiers of the PDS's
- //* created - to do this, find the // EXEC GGLOAD statements and
- //* change the value of the TO parameter.
- //*
- //* See the $$README file (of the CNTL PDS, first in this stream)
- //* for the rest of the installation instructions.
- //*
- //GGLOAD PROC CLS='*',BS='6160',U='3380',V='',
- // TRK1='30',TRK2='10',DIR='35',RLSE='RLSE',
- // PREFIX='GOPHER.INSTALL.'
- //*
- //IEBUPDTE EXEC PGM=IEBUPDTE,PARM=NEW
- //SYSPRINT DD SYSOUT=&CLS
- //SYSUT2 DD DISP=(NEW,CATLG,DELETE),DSN=&PREFIX.&TO,
- // DCB=(RECFM=FB,LRECL=80,BLKSIZE=&BS),
- // SPACE=(TRK,(&TRK1,&TRK2,&DIR),&RLSE),UNIT=&U,VOL=SER=&V
- //*
- // PEND
- //CNTL EXEC GGLOAD,TRK1='4',TO='CNTL'
- //SYSIN DD DATA,DLM='?!'
- ./ ADD NAME=$$README,SSI=010C0017
-
- ------------------------------------------------------------------------
-
- Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992
-
- MVS Gopher Server originally by Shawn Hart (Univ. of Delaware).
-
- This software is provided on an "AS IS" basis. All warranties,
- including the implied warranties of merchantability and fitness,
- are expressly denied.
-
- Provided this copyright notice is included, this software may
- be freely distributed and not offered for sale.
-
- Changes or modifications may be made and used only by the maker
- of same, and not further distributed. Such modifications should
- be mailed to the author for consideration for addition to the
- software and incorporation in subsequent releases.
-
- ------------------------------------------------------------------------
-
- MVS Gopher Client
-
- Author: Steve Bacher <seb1525@mvs.draper.com>
-
- MVS Gopher Server
-
- Author: Shawn Hart <shawn.hart@mvs.udel.edu>
- Enhancements: Steve Bacher <seb1525@mvs.draper.com>
- Customizations: Lou Joseph <CWMY5C@IRISHMVS.CC.ND.EDU>
-
- ------------------------------------------------------------------------
-
- Contents of PDS's belonging to Gopher distribution:
-
- Member PDS Type Description
-
- $$README CNTL This file
- ACCESS CNTL Sample server access file
- ALLOAD CNTL JCL to allocate GOPHER load library
- COMPILEC CNTL JCL to compile and link C source for client
- COMPILES CNTL JCL to compile and link C source for server
- GOPHERD CNTL JCL to run the GOPHER server in batch (No TSO)
- GOPHERT CNTL JCL to run the GOPHER server in batch (w. TSO)
- HELP CNTL TSO Help for Gopher client (with XPROC support)
- HELQ CNTL TSO Help for Gopher client (without XPROC)
- INSTALLC CNTL How to install the GOPHER MVS client
- INSTALLS CNTL How to install the GOPHER MVS server
- MENU CNTL Initial Gopher server menu
- GOPHER CLIST Exec by which users invoke the Gopher client
- NNMFIUCV CLIST Exec to check for multiple socket applications
- GGM... PANEL ISPF regular panels
- GG... H C headers for compilation
- GG... C C source for compilation
- ABOUT... ABOUT "About This Gopher" text
-
- --------------------------------------------------------------------
-
- Where to Go from Here:
-
- To install the GOPHER MVS client, read member INSTALLC.
-
- To install the GOPHER MVS server, read member INSTALLS.
-
- Note:
-
- You may install only the client, only the server, or both the
- client and the server. It is purely up to what your needs are.
-
- --------------------------------------------------------------------
-
- Changes:
-
- 10/19/92 - Improvements in initial startup and GOPHERRC customization
- 12/07/92 - Customizations to support SNS/TCPAccess
-
- --------------------------------------------------------------------
-
- Questions? Comments? Suggestions? Gripes? Please email to...
-
- Steve Bacher <seb@draper.com> or <seb1525@mvs.draper.com>
-
- ./ ADD NAME=ACCESS,SSI=01020059
- !
- ! Format of entries:
- !
- ! filename (fully qualified, all uppercase, no quotes)
- ! can be "DD:DDNAME" or "EXEC:EXECNAME"
- !
- ! followed by names of hosts which are authorized to access the data.
- ! If no host name list is present, all hosts are authorized
- !
- ! You may specify the same file name more than once, if you need
- ! more lines to put host names on.
- !
- ! Individual PDS members must be specified separately. A PDS without
- ! a member name establishes access only to the PDS directory.
- !
- ! Note that the default directory MUST be in this table.
- !
- ! Also note that in the case of EXECs, the EXEC must live in the
- ! library allocated to GGEXEC in the Gopher server JCL.
- !
- ! *** ANY DATA SET REFERENCED BY ANY EXEC IN THAT LIBRARY IS FULLY
- ! *** ACCESSIBLE TO GOPHER REGARDLESS OF THIS TABLE! USE THIS TABLE
- ! *** TO GOVERN CONTROL TO THE EXEC ITSELF!!!
-
- !
- ! below is default directory spec, which MUST be in this table
- !
- DD:GGGOPHER
-
- !
- ! Use the following for "About This Gopher".
- ! (Change the PDS name to match your installation.)
- ! Free free to specify the name of your MVS client host(s)
- ! for information pertinent to MVS only. mvs1 and mvs2 are examples.
- !
- DD:GGABOUT
- GOPHER.ABOUT(ABOUT)
- GOPHER.ABOUT(ABOUTC) mvs1 mvs2
- GOPHER.ABOUT(ABOUTCD) mvs1 mvs2
- GOPHER.ABOUT(ABOUTCF) mvs1 mvs2
- GOPHER.ABOUT(ABOUTCO) mvs1 mvs2
- GOPHER.ABOUT(ABOUTCQ) mvs1 mvs2
- GOPHER.ABOUT(ABOUTCS) mvs1 mvs2
- GOPHER.ABOUT(ABOUTCSC) mvs1 mvs2
- GOPHER.ABOUT(ABOUTCSL) mvs1 mvs2
- GOPHER.ABOUT(ABOUTCSM) mvs1 mvs2
- GOPHER.ABOUT(ABOUTCSR) mvs1 mvs2
- GOPHER.ABOUT(ABOUTCSW) mvs1 mvs2
- GOPHER.ABOUT(ABOUTCSX) mvs1 mvs2
- GOPHER.ABOUT(ABOUTCX) mvs1 mvs2
- GOPHER.ABOUT(ABOUTS) mvs1 mvs2
- GOPHER.ABOUT(ABOUTSA) mvs1 mvs2
- GOPHER.ABOUT(ABOUTW)
- GOPHER.ABOUT(FAQ)
-
- !
- ! Here's how to do REXX execs. Note - no arguments, only exec names
- !
- EXEC:CHECKLST client1 client2 mvs
- EXEC:WAISDIR
- EXEC:WAISLIST
- EXEC:WAISSRCH
-
- ANY.PUBLIC.SEQ.DS
- ANY.SEMI.PUBLIC.SEQ.DS goodclient1 goodclient2
- ANY.SEMI.PUBLIC.SEQ.DS goodclient3 goodclient4
-
- ! PDS without member name provides access to directory only
- ! All member names must be explicitly listed to be accessible.
-
- ANY.PUBLIC.PDS
- ANY.PUBLIC.PDS(MEMBER1)
- ANY.PUBLIC.PDS(MEMBER2)
- ANY.PUBLIC.PDS(MEMBER3)
- ANY.PUBLIC.PDS(MEMBER4)
-
-
- ANY.SEMI.PUBLIC.PDS goodclient1 goodclient2
- ANY.SEMI.PUBLIC.PDS goodclient3 goodclient4
- ANY.SEMI.PUBLIC.PDS(MEMBER1) goodclient1
- ANY.SEMI.PUBLIC.PDS(MEMBER2) goodclient2
- ANY.SEMI.PUBLIC.PDS(MEMBER3) goodclient3
- ANY.SEMI.PUBLIC.PDS(MEMBER4) goodclient4
-
- ./ ADD NAME=ALLOAD,SSI=01010051
- //JOBNAME JOB ACCOUNT,'NAME'
- //* */
- //* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- //* */
- //* This software is provided on an "AS IS" basis. All warranties, */
- //* including the implied warranties of merchantability and fitness, */
- //* are expressly denied. */
- //* */
- //* Provided this copyright notice is included, this software may */
- //* be freely distributed and not offered for sale. */
- //* */
- //* Changes or modifications may be made and used only by the maker */
- //* of same, and not further distributed. Such modifications should */
- //* be mailed to the author for consideration for addition to the */
- //* software and incorporation in subsequent releases. */
- //* */
- //*
- //* Allocate GOPHER load library before install
- //*
- //GGALLOC PROC BS='6233',U='3380',V='',
- // PRI='100',SEC='100',DIR='35'
- //*
- //IEFBR14 EXEC PGM=IEFBR14
- //ALLOCDD DD DISP=(NEW,CATLG,DELETE),DSN=&LIB,
- // DCB=(RECFM=U,BLKSIZE=&BS),
- // SPACE=(&BS,(&PRI,&SEC,&DIR)),UNIT=&U,VOL=SER=&V
- //*
- // PEND
- //*
- //* The following step allocates the load library from which the
- //* executable program will be run. If you intend to place the
- //* executable into an existing library, you can skip this step.
- //* Otherwise, the name must match the name used on the LOADLIB
- //* parameter of the GGLINK procedure in the COMPILE JCL.
- //*
- //* If you want separate libraries for the client and the server,
- //* just dup this step and give 'em different lib names.
- //*
- //ALLOC1 EXEC GGALLOC,PRI=50,SEC=50,DIR=35,
- // LIB='GOPHER.LOAD'
- //*
- ./ ADD NAME=COMPILEC
- //JOBNAME JOB ACCOUNT,'NAME'
- //* */
- //* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- //* */
- //* This software is provided on an "AS IS" basis. All warranties, */
- //* including the implied warranties of merchantability and fitness, */
- //* are expressly denied. */
- //* */
- //* Provided this copyright notice is included, this software may */
- //* be freely distributed and not offered for sale. */
- //* */
- //* Changes or modifications may be made and used only by the maker */
- //* of same, and not further distributed. Such modifications should */
- //* be mailed to the author for consideration for addition to the */
- //* software and incorporation in subsequent releases. */
- //* */
- //*********************************************************************
- //*
- //* Compile some or all GOPHER C/370 sources to make the SYSLIN input
- //* to the linkedit of the executable Gopher load module(s).
- //*
- //GGCC PROC MEMBER=,
- // SRCLIB='GOPHER.C', GOPHER C source PDS
- // HDRLIB='GOPHER.H', GOPHER C headers PDS
- // COMMHDR='TCPIP.COMMMAC', C/370 TCP/IP headers
- // C370HDR='SYS1.EDCHDRS', C/370 standard headers
- // SYSMSGS='SYS1.EDCMSGS', C/370 messages file
- // SYSMSGM='EDCMSGE', C/370 message member
- // VIOUNIT=VIO, Temporary disk unit
- // OUTCLAS='*', SYSOUT class
- // CPARMS='SOURCE EXPMAC NOAGGR NOXREF', Compile parameters
- // TEST=TEST TEST or NOTEST
- //*
- //CCOMP EXEC PGM=EDCCOMP,PARM='MARGINS(1,72) &TEST &CPARMS'
- //SYSMSGS DD DISP=SHR,DSN=&SYSMSGS(&SYSMSGM)
- //SYSIN DD DISP=SHR,DSN=&SRCLIB(&MEMBER)
- //SYSLIB DD DISP=SHR,DSN=&COMMHDR
- // DD DISP=SHR,DSN=&C370HDR
- //USERLIB DD DISP=SHR,DSN=&HDRLIB
- //SYSLIN DD DSN=&&LOADSET,UNIT=&VIOUNIT,DISP=(MOD,PASS),
- // SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)
- //SYSPRINT DD SYSOUT=&OUTCLAS
- //SYSCPRT DD SYSOUT=&OUTCLAS
- //SYSUT1 DD DSN=&&SYSUT1,UNIT=&VIOUNIT,DISP=(NEW,DELETE),
- // SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)
- //SYSUT4 DD DSN=&&SYSUT4,UNIT=&VIOUNIT,DISP=(NEW,DELETE),
- // SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)
- //SYSUT6 DD DSN=&&SYSUT6,UNIT=&VIOUNIT,DISP=(NEW,DELETE),
- // SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)
- //SYSUT7 DD DSN=&&SYSUT7,UNIT=&VIOUNIT,DISP=(NEW,DELETE),
- // SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)
- //SYSUT8 DD DSN=&&SYSUT8,UNIT=&VIOUNIT,DISP=(NEW,DELETE),
- // SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)
- //SYSUT9 DD DSN=&&SYSUT9,UNIT=&VIOUNIT,DISP=(NEW,DELETE),
- // SPACE=(32000,(30,30)),DCB=(RECFM=VB,LRECL=137,BLKSIZE=882)
- //SYSUT10 DD SYSOUT=&OUTCLAS
- //*
- // PEND
- //*
- //*********************************************************************
- //*
- //* Linkedit an executable Gopher load module.
- //*
- //* Note: If C/370 V1R2 or higher, and you have therefore accepted
- //* the "#define FETCH" in the GG header, you may delete
- //* the line that includes the ISPLINK library.
- //*
- //* Note: If TCP/IP V2 or higher, remove the PASCAL link libraries
- //* from the JCL and the AMPZMVSB card from the control deck.
- //*
- //GGLINK PROC LOADLIB='GOPHER.LOAD', Executable load library
- // PLIBASE='SYS1.PLIBASE', PL/1 link library
- // EDCBASE='SYS1.SEDCBASE', C/370 link library
- // IBMBASE='SYS1.SIBMBASE', PL/1+C common library
- // COMMTXT='TCPIP.COMMTXT', TCP/IP link library
- // PASRUN3='SYS1.PAS.SAMPRUN3', PASCAL link library
- // PASRUN1='SYS1.PAS.SAMPRUN1', PASCAL link library
- // PASMSG1='SYS1.PAS.SAMPMSG1', PASCAL link library
- // ISPLINK='ISP.V3R2M0.ISPLLIB', ISPLINK link library
- // VIOUNIT=VIO, Temporary disk unit
- // OUTCLAS='*', SYSOUT class
- // LPARMS='LIST,LET,MAP', Linkedit parameters
- // TEST=TEST TEST or NOTEST
- //*
- //LKED EXEC PGM=IEWL,PARM='AMODE(31),&TEST,&LPARMS'
- //SYSPRINT DD SYSOUT=&OUTCLAS
- //SYSLIB DD DISP=SHR,DSN=&PLIBASE
- // DD DISP=SHR,DSN=&EDCBASE
- // DD DISP=SHR,DSN=&IBMBASE
- // DD DISP=SHR,DSN=&COMMTXT
- // DD DISP=SHR,DSN=&PASRUN3 if TCP/IP V1 only
- // DD DISP=SHR,DSN=&PASRUN1 if TCP/IP V1 only
- // DD DISP=SHR,DSN=&PASMSG1 if TCP/IP V1 only
- // DD DISP=SHR,DSN=&ISPLINK if C/370 V1R1 with #undef FETCH
- //SYSLMOD DD DISP=SHR,DSN=&LOADLIB
- //SYSUT1 DD DSN=&&SYSUT1,UNIT=&VIOUNIT,DISP=(NEW,DELETE),
- // SPACE=(32000,(30,30))
- //*
- // PEND
- //*
- //GGCLIENT EXEC GGCC,MEMBER=GGCLIENT
- //GGMALLOC EXEC GGCC,MEMBER=GGMALLOC
- //GGMBRIFC EXEC GGCC,MEMBER=GGMBRIFC
- //GGMBRIFR EXEC GGCC,MEMBER=GGMBRIFR
- //GGMCLRTX EXEC GGCC,MEMBER=GGMCLRTX
- //GGMCONN EXEC GGCC,MEMBER=GGMCONN
- //GGMCSO EXEC GGCC,MEMBER=GGMCSO
- //GGMDFAIL EXEC GGCC,MEMBER=GGMDFAIL
- //GGMDIR EXEC GGCC,MEMBER=GGMDIR
- //GGMDISC EXEC GGCC,MEMBER=GGMDISC
- //GGMDISPL EXEC GGCC,MEMBER=GGMDISPL
- //GGMDUMP EXEC GGCC,MEMBER=GGMDUMP
- //GGMESRVR EXEC GGCC,MEMBER=GGMESRVR
- //GGMFREEM EXEC GGCC,MEMBER=GGMFREEM
- //GGMGETDS EXEC GGCC,MEMBER=GGMGETDS
- //GGMGETM EXEC GGCC,MEMBER=GGMGETM
- //GGMGOFOR EXEC GGCC,MEMBER=GGMGOFOR
- //GGMGSRVL EXEC GGCC,MEMBER=GGMGSRVL
- //GGMIERR EXEC GGCC,MEMBER=GGMIERR
- //GGMIGET EXEC GGCC,MEMBER=GGMIGET
- //GGMISPF EXEC GGCC,MEMBER=GGMISPF
- //GGMIVGET EXEC GGCC,MEMBER=GGMIVGET
- //GGMIVPUT EXEC GGCC,MEMBER=GGMIVPUT
- //GGMMTFER EXEC GGCC,MEMBER=GGMMTFER
- //GGMOUTS EXEC GGCC,MEMBER=GGMOUTS
- //GGMOUTTX EXEC GGCC,MEMBER=GGMOUTTX
- //GGMPMSG EXEC GGCC,MEMBER=GGMPMSG
- //GGMPROC EXEC GGCC,MEMBER=GGMPROC
- //GGMPTX EXEC GGCC,MEMBER=GGMPTX
- //GGMSOCKT EXEC GGCC,MEMBER=GGMSOCKT
- //GGMSOPT EXEC GGCC,MEMBER=GGMSOPT
- //GGMSSRVR EXEC GGCC,MEMBER=GGMSSRVR
- //GGMTNET EXEC GGCC,MEMBER=GGMTNET
- //GGMTSO EXEC GGCC,MEMBER=GGMTSO
- //GGMTYPE EXEC GGCC,MEMBER=GGMTYPE
- //GGMUNALC EXEC GGCC,MEMBER=GGMUNALC
- //GGMVTX EXEC GGCC,MEMBER=GGMVTX
- //GGMWAIS EXEC GGCC,MEMBER=GGMWAIS
- //GGMWHOIS EXEC GGCC,MEMBER=GGMWHOIS
- //GGMXTX EXEC GGCC,MEMBER=GGMXTX
- //*
- //* Link GOPHER load module. Like SMP/E, expect return code 8 when
- //* doing this from scratch. Additional one-or-two-module links
- //* will just replace the corresponding parts of the load module.
- //*
- //GGLINK EXEC GGLINK
- //LKED.SYSLIN DD DISP=(OLD,DELETE),DSN=&&LOADSET
- // DD *
- INCLUDE SYSLMOD(GGCLIENT) if included first time, RC = 8
- INCLUDE SYSLIB(AMPZMVSB) include if TCP/IP V1 only
- ENTRY CEESTART
- NAME GGCLIENT(R)
- /*
- ./ ADD NAME=COMPILES,SSI=01060050
- //JOBNAME JOB ACCOUNT,'NAME'
- //* */
- //* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- //* */
- //* This software is provided on an "AS IS" basis. All warranties, */
- //* including the implied warranties of merchantability and fitness, */
- //* are expressly denied. */
- //* */
- //* Provided this copyright notice is included, this software may */
- //* be freely distributed and not offered for sale. */
- //* */
- //* Changes or modifications may be made and used only by the maker */
- //* of same, and not further distributed. Such modifications should */
- //* be mailed to the author for consideration for addition to the */
- //* software and incorporation in subsequent releases. */
- //* */
- //*********************************************************************
- //*
- //* Compile some or all GOPHER C/370 sources to make the SYSLIN input
- //* to the linkedit of the executable Gopher load module.
- //*
- //GGCC PROC MEMBER=,
- // SRCLIB='GOPHER.C', GOPHER C source PDS
- // HDRLIB='GOPHER.H', GOPHER C headers PDS
- // COMMHDR='TCPIP.COMMMAC', C/370 TCP/IP headers
- // C370HDR='SYS1.EDCHDRS', C/370 standard headers
- // SYSMSGS='SYS1.EDCMSGS', C/370 messages file
- // SYSMSGM='EDCMSGE', C/370 message member
- // VIOUNIT=VIO, Temporary disk unit
- // OUTCLAS='*', SYSOUT class
- // CPARMS='SOURCE EXPMAC NOAGGR NOXREF', Compile parameters
- // TEST=TEST TEST or NOTEST
- //*
- //CCOMP EXEC PGM=EDCCOMP,PARM='MARGINS(1,72) &TEST &CPARMS'
- //SYSMSGS DD DISP=SHR,DSN=&SYSMSGS(&SYSMSGM)
- //SYSIN DD DISP=SHR,DSN=&SRCLIB(&MEMBER)
- //SYSLIB DD DISP=SHR,DSN=&COMMHDR
- // DD DISP=SHR,DSN=&C370HDR
- //USERLIB DD DISP=SHR,DSN=&HDRLIB
- //SYSLIN DD DSN=&&LOADSET,UNIT=&VIOUNIT,DISP=(MOD,PASS),
- // SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)
- //SYSPRINT DD SYSOUT=&OUTCLAS
- //SYSCPRT DD SYSOUT=&OUTCLAS
- //SYSUT1 DD DSN=&&SYSUT1,UNIT=&VIOUNIT,DISP=(NEW,DELETE),
- // SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)
- //SYSUT4 DD DSN=&&SYSUT4,UNIT=&VIOUNIT,DISP=(NEW,DELETE),
- // SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)
- //SYSUT6 DD DSN=&&SYSUT6,UNIT=&VIOUNIT,DISP=(NEW,DELETE),
- // SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)
- //SYSUT7 DD DSN=&&SYSUT7,UNIT=&VIOUNIT,DISP=(NEW,DELETE),
- // SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)
- //SYSUT8 DD DSN=&&SYSUT8,UNIT=&VIOUNIT,DISP=(NEW,DELETE),
- // SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)
- //SYSUT9 DD DSN=&&SYSUT9,UNIT=&VIOUNIT,DISP=(NEW,DELETE),
- // SPACE=(32000,(30,30)),DCB=(RECFM=VB,LRECL=137,BLKSIZE=882)
- //SYSUT10 DD SYSOUT=&OUTCLAS
- //*
- // PEND
- //*
- //*********************************************************************
- //*
- //* Linkedit the executable Gopher load modules.
- //*
- //* Note: If TCP/IP V2 or higher, remove the PASCAL link libraries
- //* from the JCL and the AMPZMVSB card from the control deck.
- //*
- //GGLINK PROC LOADLIB='GOPHER.LOAD', Executable load library
- // EDCBASE='SYS1.SEDCBASE', C/370 link library
- // IBMBASE='SYS1.SIBMBASE', PL/1+C common library
- // COMMTXT='TCPIP.COMMTXT', TCP/IP link library
- // PASRUN3='SYS1.PAS.SAMPRUN3', PASCAL link library
- // PASRUN1='SYS1.PAS.SAMPRUN1', PASCAL link library
- // PASMSG1='SYS1.PAS.SAMPMSG1', PASCAL link library
- // IKJLINK='SYS1.LINKLIB', IKJEFF18 link library
- // VIOUNIT=VIO, Temporary disk unit
- // OUTCLAS='*', SYSOUT class
- // LPARMS='LIST,LET,MAP', Linkedit parameters
- // TEST=TEST TEST or NOTEST
- //*
- //LKED EXEC PGM=IEWL,PARM='AMODE(31),&TEST,&LPARMS'
- //SYSPRINT DD SYSOUT=&OUTCLAS
- //SYSLIB DD DISP=SHR,DSN=&EDCBASE
- // DD DISP=SHR,DSN=&IBMBASE
- // DD DISP=SHR,DSN=&COMMTXT
- // DD DISP=SHR,DSN=&PASRUN3 if TCP/IP V1 only
- // DD DISP=SHR,DSN=&PASRUN1 if TCP/IP V1 only
- // DD DISP=SHR,DSN=&PASMSG1 if TCP/IP V1 only
- // DD DISP=SHR,DSN=&IKJLINK if C/370 V1R1 with #undef FETCH
- //SYSLMOD DD DISP=SHR,DSN=&LOADLIB
- //SYSUT1 DD DSN=&&SYSUT1,UNIT=&VIOUNIT,DISP=(NEW,DELETE),
- // SPACE=(32000,(30,30))
- //*
- // PEND
- //*
- //GGMALLOC EXEC GGCC,MEMBER=GGMALLOC
- //GGMDFAIL EXEC GGCC,MEMBER=GGMDFAIL
- //GGMUNALC EXEC GGCC,MEMBER=GGMUNALC
- //GGMOUTS EXEC GGCC,MEMBER=GGMOUTS
- //GGMPROC EXEC GGCC,MEMBER=GGMPROC
- //GGSTASK EXEC GGCC,MEMBER=GGSTASK
- //*
- //* Link GOPHER subtask module. Like SMP/E, expect return code 8
- //* doing this from scratch. Additional one-or-two-module links
- //* will just replace the corresponding parts of the load module.
- //*
- //* If recompiling the entire load module, you may want to delete
- //* the previous one from the SYSLMOD library first, or remove the
- //* INCLUDE SYSLMOD card from the JCL below.
- //*
- //GGLINKT EXEC GGLINK
- //LKED.SYSLIN DD DISP=(OLD,DELETE),DSN=&&LOADSET
- // DD *
- INCLUDE SYSLMOD(GGSTASK) if included first time, RC = 8
- INCLUDE SYSLIB(AMPZMVSB) include if TCP/IP V1 only
- INCLUDE SYSLIB(IUCVFORC)
- INCLUDE SYSLIB(EDCMTFS)
- ENTRY CEESTART
- NAME GGSTASK(R)
- /*
- //GGMMTFER EXEC GGCC,MEMBER=GGMMTFER
- //GGSERVER EXEC GGCC,MEMBER=GGSERVER
- //*
- //* Link GOPHER server module. Like SMP/E, expect return code 8
- //* doing this from scratch. Additional one-or-two-module links
- //* will just replace the corresponding parts of the load module.
- //*
- //* If recompiling the entire load module, you may want to delete
- //* the previous one from the SYSLMOD library first, or remove the
- //* INCLUDE SYSLMOD card from the JCL below.
- //*
- //GGLINKS EXEC GGLINK
- //LKED.SYSLIN DD DISP=(OLD,DELETE),DSN=&&LOADSET
- // DD *
- INCLUDE SYSLMOD(GGSERVER) if included first time, RC = 8
- INCLUDE SYSLIB(AMPZMVSB) include if TCP/IP V1 only
- ENTRY CEESTART
- NAME GGSERVER(R)
- /*
- ./ ADD NAME=GOPHERD,SSI=01060032
- //GOPHERD PROC MODULE=GGSERVER, 00010000
- // STEPLIB='GOPHER.LOAD', 00020000
- // EXECLIB='GOPHER.EXEC', 00030000
- // ACCESS='GOPHER.ACCESS', 00040000
- // ABOUT='GOPHER.ABOUT', 00050000
- // MENU='GOPHER.MENU', 00050000
- // GPARM= 00050000
- //* 00060000
- //********************************************************************* 00070000
- //* * 00080000
- //* GOPHER daemon, by Shawn Hart (U.Del.) and Steve Bacher (D.Lab.) * 00090000
- //* * 00100000
- //* Straight batch (no TSO access) * 00100000
- //* * 00100000
- //********************************************************************* 00110000
- //* 00120000
- //GOPHERD EXEC PGM=&MODULE,PARM='&GPARM' 00150001
- //STEPLIB DD DISP=SHR,DSN=&STEPLIB 00170000
- //GGEXEC DD DISP=SHR,DSN=&EXECLIB 00181002
- //SYSTSPRT DD UNIT=SYSVIO,SPACE=(TRK,(100,100)),RECFM=VBA,LRECL=255 00190000
- //SYSERR DD SYSOUT=* 00200000
- //SYSPRINT DD SYSOUT=* 00210000
- //SYSTSIN DD DUMMY 00210000
- //SYSIN DD DUMMY 00210000
- //GGDEBUG DD SYSOUT=* 00230000
- //GGABOUT DD DISP=SHR,DSN=&ABOUT 00230000
- //GGACCESS DD DISP=SHR,DSN=&ACCESS 00240000
- //GGGOPHER DD DISP=SHR,DSN=&MENU 00250000
- ./ ADD NAME=GOPHERT,SSI=01040057
- //GOPHERD PROC MODULE=GGSERVER, 00010000
- // STEPLIB='GOPHER.LOAD', 00020000
- // EXECLIB='GOPHER.EXEC', 00030000
- // ACCESS='GOPHER.ACCESS', 00040000
- // ABOUT='GOPHER.ABOUT', 00050000
- // MENU='GOPHER.MENU', 00050000
- // GPARM= 00050000
- //* 00060000
- //********************************************************************* 00070000
- //* * 00080000
- //* GOPHER daemon, by Shawn Hart (U.Del.) and Steve Bacher (D.Lab.) * 00090000
- //* * 00100000
- //********************************************************************* 00110000
- //* 00120000
- //GOPHERD EXEC PGM=IKJEFT01,DYNAMNBR=128,REGION=8M, 00150001
- // PARM='&MODULE &GPARM' 00160000
- //STEPLIB DD DISP=SHR,DSN=&STEPLIB 00170000
- //GGEXEC DD DISP=SHR,DSN=&EXECLIB 00181002
- //SYSTSPRT DD UNIT=SYSVIO,SPACE=(TRK,(100,100)),RECFM=VBA,LRECL=255 00190000
- //SYSERR DD SYSOUT=* 00200000
- //SYSPRINT DD SYSOUT=* 00210000
- //SYSTSIN DD DUMMY 00220000
- //SYSIN DD DUMMY 00230000
- //GGDEBUG DD SYSOUT=* 00230000
- //GGABOUT DD DISP=SHR,DSN=&ABOUT 00230000
- //GGACCESS DD DISP=SHR,DSN=&ACCESS 00240000
- //GGGOPHER DD DISP=SHR,DSN=&MENU 00250000
- ./ ADD NAME=HELP,SSI=01000051
- )F Function -
-
- GOPHER is a distributed document delivery service, or, more generally,
- a networked information retrieval service. It allows you to access
- numerous types of data on various hosts in a transparent fashion.
- GOPHER presents you with a hierarchical display of information sources
- which are accessed via a client/server communications link.
-
- There are GOPHER clients for all common hardware platforms. The MVS
- version runs as an ISPF dialog application.
-
- When you use the GOPHER client, information about your use of GOPHER
- is stored in a data set called GOPHERRC. If you don't have one,
- GOPHER will create it for you.
-
- For more information on customizing your GOPHER environment, get
- into Gopher and select "About This GOPHER".
-
- )I GOPHLOC - local GOPHER help goes in member GOPHLOC
-
- )X Syntax -
-
- %GOPHER
- LOCAL
- SERVER(hostname)
- PATH(pathname)
- PORT(portnumber)
- DESCRIPTION(text)
- FORCE
- DEBUG
- TEST
-
- Required: none
-
- )O Operands -
-
- ))LOCAL
-
- Specify LOCAL if you want to enter GOPHER in "serverless"
- mode - i.e. start up with your private GOPHER menu.
- Specifying LOCAL accomplishes two things:
-
- (1) It sets the server to "-", meaning local access.
- Therefore, you must also provide a path, either
- via the PATH operand or via a "localmenu:" spec
- in your GOPHERRC file.
-
- (2) It allows you to use GOPHER even if there are
- other TCP/IP socket applications active elsewhere
- in your TSO session. However, it will not allow
- you to connect to any GOPHER servers, even if you
- have a local menu item that points to one.
-
- For information on how to set up GOPHER menus, get into
- GOPHER and select "About This Gopher".
-
- ))SERVER(hostname)
-
- The host name (or IP address) of a Gopher server.
- If this is not given, GOPHER looks in your GOPHERRC
- to find what server to connect to. If it can't find
- an appropriate specification, you will have to enter
- a server name on the startup panel.
-
- A server name of a single minus sign (-) is a special
- case, signifying local (serverless) access to your
- own private GOPHER data. In this case, you must tell
- GOPHER where your menu is, either via the PATH operand
- or in the GOPHERRC file.
-
- ))PATH(pathname)
-
- The path name to be passed to the Gopher server, or
- used in local access as your initial menu. Although
- the exact interpretation of the pathname string varies
- depending on the server, both the MVS server and the
- local GOPHER access feature interpret the pathname
- as the FULLY QUALIFIED WITHOUT QUOTES name of an MVS
- data set containing a gopher menu. For information
- about the format of a gopher menu, see operand MENU.
-
- ))PORT(portnumber)
-
- You should never need to specify this field unless
- someone has set up a special kind of Gopher server
- that requires a unique port number.
-
- ))DESCRIPTION(text)
-
- A text string giving the heading to be displayed for
- the initial directory of Gopher goodies. Normally
- either the Gopher server or the Gopher client will
- have a default value for this, or you can specify
- a description of your liking in your GOPHERRC file.
-
- ))FORCE
-
- GOPHER tries to determine if there is a TCP/IP socket
- application active elsewhere in your TSO environment
- before starting up, to prevent TCP/IP errors. If it
- tells you that there is another client active but in
- truth there is none and you know it, you can use the
- FORCE keyword to make GOPHER proceed whether it finds
- this to be the case or not.
-
- Using the LOCAL operand is one way to avoid this entire
- scenario. However, that won't allow you to access any
- Gopher servers on the network.
-
- ))DEBUG
-
- Set debugging mode on. You must preallocate a file to
- ddname GGDEBUG for this to work. This can be allocated
- to the terminal or a log file. When debug mode is on,
- messages describing memory allocation and deallocation
- and GOPHER queries sent are dumped to the debug file.
-
- ))TEST
-
- Activate C/370 interactive test (INSPECT). GOPHER must
- have been compiled with the TEST option for this to be
- effective. Note that you can also issue the TEST command
- inside GOPHER to get to INSPECT, again provided that
- GOPHER was compiled with the TEST option.
-
- ./ ADD NAME=HELQ,SSI=01000025
- )F Function -
-
- GOPHER is a distributed document delivery service, or, more generally,
- a networked information retrieval service. It allows you to access
- numerous types of data on various hosts in a transparent fashion.
- GOPHER presents you with a hierarchical display of information sources
- which are accessed via a client/server communications link.
-
- There are GOPHER clients for all common hardware platforms. The MVS
- version runs as an ISPF dialog application.
-
- When you use the GOPHER client, information about your use of GOPHER
- is stored in a data set called GOPHERRC. If you don't have one,
- GOPHER will create it for you.
-
- For more information on customizing your GOPHER environment, get
- into Gopher and select "About This GOPHER".
-
- )I GOPHLOC - local GOPHER help goes in member GOPHLOC
-
- )X Syntax -
-
- %GOPHER
- LOCAL
- FORCE
- DEBUG
- TEST
-
- Required: none
-
- )O Operands -
-
- ))LOCAL
-
- Specify LOCAL if you want to enter GOPHER in "serverless"
- mode - i.e. start up with your private GOPHER menu.
- Specifying LOCAL accomplishes two things:
-
- (1) It sets the server to "-", meaning local access.
- Therefore, you must also provide a path via a
- "localmenu:" spec in your GOPHERRC file.
-
- (2) It allows you to use GOPHER even if there are
- other TCP/IP socket applications active elsewhere
- in your TSO session. However, it will not allow
- you to connect to any GOPHER servers, even if you
- have a local menu item that points to one.
-
- For information on how to set up GOPHER menus, get into
- GOPHER and select "About This Gopher".
-
- ))FORCE
-
- GOPHER tries to determine if there is a TCP/IP socket
- application active elsewhere in your TSO environment
- before starting up, to prevent TCP/IP errors. If it
- tells you that there is another client active but in
- truth there is none and you know it, you can use the
- FORCE keyword to make GOPHER proceed whether it finds
- this to be the case or not.
-
- Using the LOCAL operand is one way to avoid this entire
- scenario. However, that won't allow you to access any
- Gopher servers on the network.
-
- ))DEBUG
-
- Set debugging mode on. You must preallocate a file to
- ddname GGDEBUG for this to work. This can be allocated
- to the terminal or a log file. When debug mode is on,
- messages describing memory allocation and deallocation
- and GOPHER queries sent are dumped to the debug file.
-
- ))TEST
-
- Activate C/370 interactive test (INSPECT). GOPHER must
- have been compiled with the TEST option for this to be
- effective. Note that you can also issue the TEST command
- inside GOPHER to get to INSPECT, again provided that
- GOPHER was compiled with the TEST option.
-
- ./ ADD NAME=INSTALLC,SSI=01070035
-
- Directions for Installing the GOPHER MVS Client
-
- Assuming the PDS's have been created:
-
- 1. Customize the ALLOAD and COMPILEC JCL members to reflect your
- local conventions. Note: If you intend to place the executable into
- an existing library, you can suppress that part of the ALLOAD JCL.
- The name of the data set created must match across both members.
-
- 2. Customize the GGUSER header file as shown by the comments therein.
- Note in particular the defines for your TCP/IP and your C compiler.
- There are changes to the linkedit JCL that are related to these.
-
- 3. Customize the GOPHER exec to define the names of the MVS libraries
- to contain the panel and load library members. The load library must
- be the one specified in the ALLOAD JCL, if you are creating it anew.
- Observe the comments relating to the use of LIBDEF and ISPF APPLIDs.
-
- It is in the GOPHER exec that you will also customize the name of the
- default Gopher server. Note that the user's GOPHERRC file gets built
- from the contents of this exec.
-
- Note that if you install one of the REXX execs, you must also install
- the NNMFIUCV exec in the same library. This exec implements a rude
- check for an existing TCP/IP socket application (e.g. another GOPHER)
- in a different PIE MultiTSO session. It prevents your users from
- crashing TCP/IP, so it is highly recommended that you make use of it.
-
- 4. If you are running ISPF Version 2 or earlier, edit the GOPHER panels
- whose names begin "GGMP...". These are popups, and will not work
- under ISPF Version 2 unless you change the )BODY line. Remove the
- WINDOW(...) parameter from the )BODY line of each panel so that the
- line just says )BODY or )BODY EXPAND(``), as the case may be.
-
- Now, to install:
-
- 5. Submit the ALLOAD JCL to allocate the load library from which the
- executable program will be run. If you intend to place the executable
- into an existing library, you can skip this step, but you should make
- sure that there is no previous load module named GGCLIENT in the load
- library of your choice before you proceed.
-
- 6. Submit the COMPILEC JCL to compile all the C sources and create
- the executable Gopher load module.
-
- The first time you run this you can expect a return code of 8 from
- the linkedit. Like SMP/E, this is OK if the only reason is an IEW0342
- because the "INCLUDE SYSLMOD(GGCLIENT)" did not find an existing load
- module. If you get IEW0132 (unresolved external reference) or
- IEW0241 (ESD type definition conflict), your linkedit went awry.
- Don't use the resultant load module. Check the libraries you
- specified on the link step to see what went wrong.
-
- In the future, if you have to recompile individual modules, you can use
- the same JCL to compile only those modules, and the link will include
- the new modules in the existing executable load module.
-
- *********************************************************************
-
- IMPORTANT: If you are running TCP/IP V2R2 or higher on MVS, you must
- change the following library names in the compile and link JCL:
-
- TCPIP.COMMMAC should be changed to TCPIP.SEZACMAC
- TCPIP.COMMTXT should be changed to TCPIP.SEZACMTX
-
- If you are using SNS/TCPAccess, use these library names, or
- whatever names are defined at your installation:
-
- TCPIP.COMMMAC should be changed to SNSTCP.V110.H
- TCPIP.COMMTXT should be changed to SNSTCP.V110.CILIB
-
- *********************************************************************
-
- Note: If you have defined C370V1 in the GGUSER header file, you must
- also include the system linklist load library or libraries containing
- ISPLINK, ISPEXEC and IKJEFF18 when linking. Otherwise you may delete
- the lines from the linkedit JCL that reference them.
-
- Note: You need not include the PASCAL libraries or the AMPZMVSB
- module if you are using TCP/IP Version 2 or higher, in which case
- you must also define TCPIPV2 in the GGUSER headerfile.
-
- 7. Copy all the members of the panel PDS into the ISPF panel library
- specified in the GOPHER exec.
-
- 8. Copy one of the help members (HELP or HELQ) from the CNTL PDS into
- your local TSO HELP library under the name GOPHER. You may also
- create an additional HELP member called GOPHLOC containing
- information local to your site, if you wish.
-
- Which CNTL member should you use? If you don't have XPROC, use HELQ.
- If you do have XPROC, use HELP. You will have to modify your GOPHER
- clist either way. If you don't have XPROC, you should get it,
- because you can specify more options on Gopher if you do. You can
- get XPROC via USC's "MVS network server" code distribution service.
- For more information about this, send an email message to
- SERVICE@MVSA.USC.EDU - or SERVICE@USCMVSA, which will normally give
- better results if you have a BITNET (NJE) return address.
-
- 9. Create the "About This Gopher" PDS from the ABOUT PDS. This has
- all the text users should see when they select the "About This Gopher"
- item from the MVS client. It also contains all the documentation you
- need about setting up the client and the server, as well as creating
- menus and REXX execs for use with MVS Gopher. You may have already
- done this as part of the server install, but it should also be
- available from the client in "local" (serverless) mode, so that is
- why I mention it here.
-
- --------------------------------------------------------------------
-
- Note: Make sure that the C/370 run time library is available,
- either in the system link list or in the ISPLLIB concatenation,
- before attempting to run GOPHER.
-
- If the C/370 runtime library is not in the link list or otherwise
- available to ISPF at execution time, you may arrange for it to be
- allocated via LIBDEF in the GOPHER exec (I haven't tried this).
-
- ./ ADD NAME=INSTALLS,SSI=01080018
-
- Directions for Installing the GOPHER MVS Server
-
- Assuming the PDS's have been created:
-
- 1. Customize the ALLOAD and COMPILES JCL members to reflect your
- local conventions. Note: If you intend to place the executable into
- an existing library, you can suppress that part of the ALLOAD JCL.
- The name of the data set created must match across both members.
-
- 2. Customize the GGUSER header file as shown by the comments therein.
- Note in particular the defines for your TCP/IP and your C compiler.
- There are changes to the linkedit JCL that are related to these.
-
- Now, to install:
-
- 3. Submit the ALLOAD JCL to allocate the load library from which the
- executable program will be run. If you intend to place the executable
- into an existing library, you can skip this step, but you should make
- sure that there is no previous load module named GGSERVER or GGSTASK
- in the load library of your choice before you proceed.
-
- 4. Submit the COMPILES JCL to compile all the C sources and create
- the executable Gopher load modules.
-
- The first time you run this you can expect return codes of 8 from
- the linkedit. Like SMP/E, this is OK if the only reason is an IEW0342
- because the "INCLUDE SYSLMOD(...)" did not find an existing load
- module. If you get IEW0132 (unresolved external reference) or
- IEW0241 (ESD type definition conflict), your linkedit went awry.
- Don't use the resultant load module. Check the libraries you
- specified on the link step to see what went wrong.
-
- In the future, if you have to recompile individual modules, you can use
- the same JCL to compile only those modules, and the link will include
- the new modules in the existing executable load module.
-
- *********************************************************************
-
- IMPORTANT: If you are running TCP/IP V2R2 or higher on MVS, you must
- change the following library names in the compile and link JCL:
-
- TCPIP.COMMMAC should be changed to TCPIP.SEZACMAC
- TCPIP.COMMTXT should be changed to TCPIP.SEZACMTX
-
- If you are using SNS/TCPAccess, use these library names, or
- whatever names are defined at your installation:
-
- TCPIP.COMMMAC should be changed to SNSTCP.V110.H
- TCPIP.COMMTXT should be changed to SNSTCP.V110.CILIB
-
- *********************************************************************
-
- Note: If you have defined C370V1 in the GGUSER header file, you must
- also include the system linklist load library containing IKJEFF18
- when linking. Otherwise you may delete the line from the linkedit
- JCL that references it.
-
- Note: You need not include the PASCAL libraries or the AMPZMVSB
- module if you are using TCP/IP Version 2 or higher, in which case
- you must also define TCPIPV2 in the GGUSER headerfile.
-
- 5. Create the "About This Gopher" PDS from the ABOUT PDS. This has
- all the text users should see when they select the "About This Gopher"
- item from the MVS client. It also contains all the documentation you
- need about setting up the client and the server, as well as creating
- menus and REXX execs for use with MVS Gopher. You may have already
- done this as part of the client install.
-
- *** NOTE: In member MENU, you must change the line that reads
- "PATH=GOPHER.ABOUT.PDS(ABOUT)" to reflect the actual name of your
- ABOUT PDS. If you are using an earlier distribution of the MVS
- Gopher server that has the line PATH=DD:GGABOUT(ABOUT), then you
- must change that as well, because that won't work to get additional
- PDS members as the user climbs down the Gopher tree.
-
- 6. Create your Gopher access file. See the instructions in the
- "About This Gopher" PDS for the format.
-
- 7. Create the MVS Gopher started task JCL from either of the samples
- given in GOPHERD and GOPHERT. The GOPHERT is recommended so that you
- can use REXX execs that issue TSO commands, but you may not want to
- use this for security reasons. Either way, customize liberally.
-
- Started task parameters:
-
- MODULE=GGSERVER the Gopher server load module in STEPLIB
- STEPLIB='GOPHER.LOAD' the load library containing the above
- EXECLIB='GOPHER.EXEC' the PDS containing server REXX execs
- ACCESS='GOPHER.ACCESS' the installation access file (sequential)
- ABOUT='GOPHER.ABOUT' the PDS containing "About This Gopher" info
- MENU='GOPHER.MENU' the initial gopher menu (sequential)
- GPARM= the server parameters (e.g. -d for debug)
-
- Note: if you specify GPARM='-D', a GGDEBUG DD must be included.
-
- --------------------------------------------------------------------
-
- Note: Make sure that the C/370 run time library is available,
- either in the system link list or in the STEPLIB concatenation,
- before attempting to run GOPHER.
-
- ./ ADD NAME=MENU,SSI=01020056
- gopher_menu
-
- TYPE=FILE
- NAME=About This Gopher
- PATH=GOPHER.ABOUT.PDS(ABOUT)
- HOST=+
- END
-
- TYPE=DIRECTORY
- NAME=Library/Information Services
- PATH=SYS0008.GOPHER.LIBRARY(LIBRS)
- HOST=MVS.UDEL.EDU
- END
-
- TYPE=TELNET
- NAME=UDINFO - University of Delaware Information
- HOST=UDINFO.UDEL.EDU
- END
-
- TYPE=DIRECTORY
- NAME=Network and System Services Computer Systems
- PATH=SYS0008.GOPHER.DIR(UDTELNET)
- HOST=MVS.UDEL.EDU
- END
-
- TYPE=DIRECTORY
- NAME=Weather Across the Country
- PATH=1/Weather
- HOST=mermaid.micro.umn.edu
- PORT=150
- END
-
- TYPE=DIRECTORY
- NAME=Other Gopher and Information Servers
- PATH=1/Other Gopher and Information Servers
- HOST=gopher.micro.umn.edu
- END
-
- TYPE=DIRECTORY
- NAME=How to use BITNET LISTSERV Servers
- PATH=SYS0008.GOPHER.DIR(LISTSERV)
- HOST=MVS.UDEL.EDU
- END
-
- TYPE=DIRECTORY
- NAME=University of Delaware Newspapers
- PATH=SYS0008.GOPHER.DIR(PAPERS)
- HOST=MVS.UDEL.EDU
- END
-
- /*
- ./ ENDUP
- ?!
- //ABOUT EXEC GGLOAD,TRK1='5',TO='ABOUT'
- //SYSIN DD DATA,DLM='?!'
- ./ ADD NAME=ABOUT,SSI=01040045
- gopher_menu
-
- TYPE=FILE
- NAME=What Is Gopher?
- PATH=(ABOUTW)
- HOST=+
- END
-
- TYPE=FILE
- NAME=Gopher FAQ (Frequently Asked Questions) List
- PATH=(FAQ)
- HOST=+
- END
-
- TYPE=DIRECTORY
- NAME=Using The Gopher MVS Client
- PATH=(ABOUTC)
- HOST=+
- END
-
- TYPE=DIRECTORY
- NAME=Administering the Gopher MVS Server
- PATH=(ABOUTS)
- HOST=+
- END
-
-
- ./ ADD NAME=ABOUTC,SSI=01030000
- gopher_menu
-
- TYPE=FILE
- NAME=Overview - Using Gopher on MVS
- PATH=(ABOUTCO)
- HOST=+
- END
-
- TYPE=FILE
- NAME=Directory Mode - Viewing a Gopher Directory
- PATH=(ABOUTCD)
- HOST=+
- END
-
- TYPE=FILE
- NAME=File Mode - Browsing a Gopher File
- PATH=(ABOUTCF)
- HOST=+
- END
-
- TYPE=FILE
- NAME=Query Mode - Executing a Gopher Query
- PATH=(ABOUTCQ)
- HOST=+
- END
-
- TYPE=FILE
- NAME=Extracting Gopher Text
- PATH=(ABOUTCX)
- HOST=+
- END
-
- TYPE=DIRECTORY
- NAME=Customizing Your Gopher Startup
- PATH=(ABOUTCS)
- HOST=+
- END
-
-
- ./ ADD NAME=ABOUTCD,SSI=01000031
- This text has not been written yet.
- ./ ADD NAME=ABOUTCF,SSI=01000042
- This text has not been written yet.
- ./ ADD NAME=ABOUTCO,SSI=01000013
- The following is modified from Allan Tuchman's XGOPHER help.
-
- Gopher on MVS is an ISPF dialog interface to the Gopher
- information delivery system from the University of Minnesota.
-
- The initial panel asks you to specify the name of the Gopher server
- host. Normally you leave the other input fields alone.
-
- You may also specify a hostname of "-", which means that you want
- to use your own private Gopher data without going through a server.
- When you do this, you must provide the path name to your private
- top-level menu (data set name, FULLY QUALIFIED, WITHOUT QUOTES).
-
- Assuming that the top-level path points to a valid Gopher menu,
- the initial display will show the top level directory of
- gopher information available. Selecting an item from this
- list will fetch the contents of a file, subdirectory, or
- other information. The directory display may be updated to
- show the new subdirectory.
-
- To select an item, type "S" in front of it and press ENTER.
- This puts you into ISPF BROWSE mode on the text of the item.
- You may also type "Q" in front of an item to see it in text format
- even if it is a directory. If you have retrieved an item, you may
- type "E" in front of it to extract it into a file - but you may
- do this more easily via the EXTract command from within BROWSE.
-
- Some gopher file types are not supported by the current client.
- These will not appear on your menus. Furthermore, you may not
- be permitted to access some items, depending upon the server
- and the host from which you are trying to access them. These
- restrictions do not apply to local mode, where you can access
- anything that you have local permission to read.
-
- The Gopher MVS client is written by Steve Bacher at Draper Laboratory
- (copyright 1992).
-
- ./ ADD NAME=ABOUTCQ,SSI=01000047
- This text has not been written yet.
- ./ ADD NAME=ABOUTCS,SSI=01030002
- gopher_menu
-
- Type=FILE
- Name=Customizing Your Gopher Startup
- Path=(ABOUTCSC)
- Host=+
- End
-
- Type=FILE
- Name=What Happens When You Start Up Gopher
- Path=(ABOUTCSW)
- Host=+
- End
-
- Type=FILE
- Name=Requesting Local (Serverless) Access
- Path=(ABOUTCSL)
- Host=+
- End
-
- Type=FILE
- Name=The GOPHERRC File
- Path=(ABOUTCSR)
- Host=+
- End
-
- Type=FILE
- Name=Defining GOPHER Menus
- Path=(ABOUTCSM)
- Host=+
- End
-
- Type=FILE
- Name=REXX Exec Interface
- Path=(ABOUTCSX)
- Host=+
- End
-
- ./ ADD NAME=ABOUTCSC,SSI=01010046
-
- =======================================================================
-
- Customizing Your Gopher Startup
-
- =======================================================================
-
- When you use the GOPHER client, information about your use of GOPHER
- is stored in a data set called GOPHERRC. If you don't have one,
- GOPHER will create it for you.
-
- Your default startup menu will contain a single item pointing to a
- GOPHER server on MVS, whether such a server is available or not.
- However, you can ask GOPHER to display a different startup menu for
- you. This startup menu may have entries for the GOPHER server
- on MVS and one for your own private (local) data, which is accessed
- without querying a server.
-
- To get GOPHER to set up a different startup menu, you must edit the
- GOPHERRC file. Note that you may set up the GOPHER startup menu to
- include a pointer to your local data - but you have to create that
- local data in order to use it.
-
- Editing the GOPHERRC file should be easy. Just follow the
- instructions in the comments of the file itself. For information
- about the contents of GOPHERRC, see the HELP for operand GOPHERRC.
-
- ./ ADD NAME=ABOUTCSL,SSI=01000056
-
- =======================================================================
-
- Requesting Local (Serverless) Access
-
- =======================================================================
-
- The LOCAL operand on the GOPHER command is a convenient way of
- requesting "local" serverless mode. Specify LOCAL on the GOPHER
- command if you want to enter GOPHER in "serverless" mode - i.e.
- start up with your private GOPHER menu. Specifying LOCAL
- accomplishes two things:
-
- (1) It sets the server to "-", meaning local access. Therefore, you
- must also provide a path, either via the PATH operand on the
- GOPHER command or via a "localmenu:" spec in your GOPHERRC file,
- so that GOPHER knows where to look for your private data. The
- path is a data set name, FULLY QUALIFIED WITHOUT QUOTES.
-
- (2) It allows you to use GOPHER even if there are other TCP/IP socket
- applications active elsewhere in your TSO session. However, it
- will not allow you to connect to any GOPHER servers, even if you
- have a local menu item that points to one.
-
- If you do not specify a server and there is no specification in
- your GOPHERRC file for one, then GOPHER will display a startup
- ISPF panel asking you to specify a server name and, optionally,
- a path name. (Don't touch the port number!)
- ./ ADD NAME=ABOUTCSM,SSI=01030019
-
- =======================================================================
-
- Defining Gopher Menus
-
- =======================================================================
-
- This is a description of how to define GOPHER menus that can be used
- either for your own private data or by the GOPHER server administrator
- on MVS to define publicly accessible data.
-
- Bear in mind that the menu may be used to specify data meaningful to
- a server other than MVS. Therefore, the descriptions here should be
- interpreted in two ways:
-
- (1) how to define MVS-resident information resources
-
- (2) how to request information resources from other GOPHER servers
-
- ------------------------------------------------------------------------
-
- How To Define MVS-Resident Information Resources
-
- The Gopher server (and the Gopher client, in "local" mode) determines
- how to return information to the client via menus. These menus are
- plain MVS data sets with a particular structure.
-
- An MVS gopher menu is a sequential data set or PDS member with the
- following format:
-
- * the first line contains the string GOPHER_MENU
- (in upper, lower or mixed case)
-
- * the rest of the file contains blocks of information like this:
-
- TYPE=type
- NAME=name
- PATH=path
- HOST=host
- PORT=port
- END
-
- For compatibility with earlier versions of the MVS Gopher server,
- the following are also accepted:
-
- DISPLAY= is equivalent to NAME=
- SELECTOR= is equivalent to PATH=
-
- Explanations
-
- TYPE=type
-
- The type of Gopher entity (FILE, DIRECTORY, INDEX, etc.).
- In other words, one of the following:
-
- FILE - the item is an MVS data set with text to be displayed.
- The path name is the file name or a REXX exec spec.
- DIRECTORY - the item is another Gopher directory.
- The path name is the file name or a REXX exec spec.
- INDEX - the item is a full text search item, which means that
- the client will query the user for a search string
- which will be passed to the server along with the
- pathname. For the MVS server. it only makes sense for
- the pathname to be a REXX exec specification. The path
- and the user's string are given to the host, which
- returns a menu of selections. See also WHOIS.
- TELNET - the item is a Telnet server.
- The path name is ignored. The port number should be
- omitted or set to 0, unless an alternate TELNET port
- is required by the server referenced by HOST.
- WHOIS - the item is a "whois" query. This is similar to the
- INDEX type, except that the server returns a file
- rather than a menu. This is not (yet) an official
- part of the Gopher protocol, though it does appear in
- certain (patched) versions of other implementations.
-
- NAME=name
-
- The descriptive string that will appear in the Gopher client's
- display of menu selections for this item. Make this as human as
- possible. Case is preserved.
-
- PATH=path
-
- The pathname to be passed to the Gopher server to retrieve the
- item. See below for a fuller description.
-
- HOST=host
-
- The name of the Gopher server host that will process the request.
- See below for a fuller description.
-
- PORT=port
-
- The TCP/IP port to connect to. For Gopher, this should always be
- port 70 (except for a TELNET type, whose port defaults to the
- standard TELNET port if zero or omitted). If this is omitted, then
- the default port number is taken.
-
- END
-
- Required to keep menu entries separate.
-
- Comment lines may be freely included, starting with '#' in
- the first column of data.
-
- More about Path Names
-
- Note that the format of a path depends on which Gopher server is
- going to be processing the entry, as defined by the HOST= field.
- If the entry is going to a different Gopher server, then the
- pathname format depends on that server. For example, a Unix server
- would expect a Unix file name with a slash.
-
- A path name for the MVS Gopher may be one of the following:
-
- * A fully qualified MVS data set name, without quotes, identifying
- a sequential text data set or PDS member. If TYPE=FILE, this is
- text. If TYPE=DIRECTORY, this is a gopher menu as described above.
-
- * A fully qualified MVS data set name, without quotes, identifying a
- PDS (no member). This causes the MVS Gopher server to return a
- list of member names of the PDS in Gopher directory format. This
- is valid only with TYPE=DIRECTORY. Member aliases are included in
- the resulting list.
-
- * A member name enclosed in parentheses. This is treated as
- a full PDS member. In other words, the MVS Gopher server will use
- the name of the PDS in which the menu itself was found.
- This allows you to move PDS's full of Gopher menus around without
- having to worry about changing all the path names. This happens
- only when the menu itself is a PDS member and the host is the
- same as the local host (MVS for the server, - for local mode).
- Specifying HOST=+ is recommended for this.
-
- * A string "DD:ddname" or "DD:ddname(member)", identifying a file by
- MVS ddname a la C/370. Valid with either TYPE=FILE or
- TYPE=DIRECTORY, so the ddname can point to text or a menu.
- However, if the ddname happens to be allocated to a PDS, it does
- NOT work like a directory above - it's just illegal and will
- probably cause lossage.
-
- Each member is treated as a Gopher FILE. The NAME field is
- set to the member name. If you want to do anything fancier
- than this, you will have to construct your own Gopher menu.
-
- * A string "EXEC:execname args", which specifies the name of a
- REXX exec to be executed to return the data. Valid with any
- and all types. To learn more about how to make use of this
- feature, please go back to the "About This Gopher" tree and
- read up on using REXX execs with MVS Gopher.
-
- If you are using your own private GOPHER data via local access
- and you want to run REXX execs, you must have a "localexec:"
- line in your GOPHERRC file identifying your REXX exec library.
-
- More About Host Names
-
- You may find that some Gopher servers insist on appending the
- network's domain name to local server hostnames. You should check
- with your network gurus to make sure that this will work with your
- TCP/IP host lookup. The MVS server will accept hostnames either
- with or without the domain name appended - this applies to the
- specification of hostnames in the Gopher access table as well -
- but other Gopher servers may not.
-
- Two special cases:
-
- A plus sign (HOST=+) means that the host is the same host as the one
- that is looking at the directory entry - i.e. the server that is
- serving up this menu. The Gopher server simply plugs in its own host
- name at that point. This is NOT part of the Gopher protocol, but
- merely a server hack.
-
- A minus sign (HOST=-) means that access to this item will be in
- "local" (serverless) mode. This is recognized only by the MVS Gopher
- client. It means that the client will do the retrieval itself,
- without asking a server to do it.
-
- The directory-processing code, when invoked in "local mode", will
- treat HOST=+ as HOST=- since the current host is the local mode
- operation in that case. Therefore, using HOST=+ is recommended
- so that one can port one's local GOPHER menus to the public server
- at some point.
-
- A REXX exec that generates menus dynamically can use - as a hostname,
- but not +.
-
- ------------------------------------------------------------------------
-
- How To Request Information Resources From Other GOPHER Servers
-
- Rather than describe the standard format of a Gopher menu here,
- I recommend that you go to your nearest Unix box and type
-
- man gopherd
-
- That should tell you all you need to know about Unix gopher servers.
- If your gopher server is on some other kind of machine, then go find
- the documentation for that machine's Gopher menus.
-
- The purpose of the above exercise is primarily to determine the format
- of a path name understood by a given Gopher server. Once you know that,
- you can build a Gopher menu the MVS Gopher will understand, according to
- the format described in the top section. Set the host to point to
- the other Gopher server, who will interpret the other items in the menu.
-
- ------------------------------------------------------------------------
-
- Dynamic Generation of GOPHER Menus
-
- If you want to be able to generate a Gopher menu dynamically,
- you can do this via the REXX interface. You also must understand
- the Gopher protocol. A Gopher menu is really a text representation
- of the actual protocol, which goes like this:
-
- filetype -tab- name -tab- path -tab- host -tab- port
-
- where -tab- is the EBCDIC (on MVS) or ASCII (on other box) tab
- character, and filetype is a single character. The filetypes
- supported by the MVS Gopher server are:
-
- 0 - flat file
- 1 - directory
- 2 - error
- 7 - index
- 8 - TELNET
- w - whois (experimental)
-
- A REXX exec that wants to generate a Gopher menu must output lines
- in this format. For more information, go back to the Gopher tree
- for "About This Gopher" and look up information on the REXX interface.
-
- ./ ADD NAME=ABOUTCSR,SSI=01010039
-
- =======================================================================
-
- The GOPHERRC File
-
- =======================================================================
-
- When you use the GOPHER client, you need a file called GOPHERRC
- which stores information about your use of GOPHER. If you don't
- have one, GOPHER will create it for you. The file initially
- contains:
-
- the initial path/name/host/port specification, which tells
- GOPHER what to display on startup. By default this is the
- standard GOPHER server info on MVS. However, you can add
- to your GOPHERRC a specification for local GOPHER by
- editing GOPHERRC and activating one of the following:
-
- - the other "initial:" spec which points to your own startup menu,
- overriding the one you'd get otherwise
-
- - the localmenu: and localexec: lines.
-
- localmenu: is equivalent to specifying an alternate initial:
- spec of host=- (dash) and path=localmenu_name. When you use
- the LOCAL operand of the GOPHER command, localmenu: is what
- GOPHER looks for as the pathname if you don't provide one on
- the command.
-
- localexec: is required if you want to use your own library of
- GOPHER rexx execs. This is valid for LOCAL access only.
-
- Some option defaults are stored in the GOPHERRC file.
- Note that this is not yet implemented.
-
- The GOPHER client will store bookmarks (as you create them)
- at the end of your GOPHERRC file. Note that this feature
- is not yet implemented.
-
- If you have a newly created GOPHERRC file, you can read the
- comments to guide you in customizing the file.
- ./ ADD NAME=ABOUTCSW,SSI=01000034
-
- =======================================================================
-
- What Happens When You Start Up GOPHER?
-
- =======================================================================
-
- What you see when you start up GOPHER depends on what you have
- specified, either on the command line or in the GOPHERRC file.
- In general, command operands override GOPHERRC specifications.
-
- GOPHER does its thing by connecting to a Gopher server somewhere
- on your network. If you do not specify otherwise, this server is
- assumed to be MVS (the host where you are running this client).
- The default GOPHERRC file specifies this as the server.
- The startup menu you see is the one defined by the administrator
- of that server.
-
- You can request a different server or a different startup menu,
- either by modifying the GOPHERRC file or by specifying command
- operands. The SERVER operand tells GOPHER to get a startup menu
- from a different server, and the PATH operand tells GOPHER what
- startup menu to request (the contents of the path depend on what
- server you point to and what it's looking for, but it is typically
- the name of a file on that system that contains a Gopher menu).
-
- You can also use GOPHER to access your own private data by requesting
- "local" (serverless) mode. A server name of a single dash "-" means
- local access. In this case, you must provide a path name so that
- GOPHER knows where to look for your data. The path name is the name
- of a data set containing your GOPHER menu - it must be FULLY QUALIFIED
- AND WITHOUT QUOTES. The path name can be provided either as a command
- operand or in the GOPHERRC file.
- ./ ADD NAME=ABOUTCSX,SSI=01020059
- =======================================================================
-
- REXX Exec Interface
-
- =======================================================================
-
- You can request the MVS Gopher server (or the MVS Gopher client, in
- "local" (serverless) mode) to retrieve information dynamically by
- executing a REXX exec. To request this, you define a menu entry
- with the following PATH= field:
-
- PATH=EXEC:execname args
-
- In the case of EXEC:, the REXX exec identified by "execname" is
- executed, along with the arguments "args" given. For example:
-
- PATH=EXEC:MYEXEC ANY ARGS
-
- will cause the MYEXEC exec to be executed with "ANY ARGS" as the
- single argument string.
-
- If the TYPE is INDEX, the search string submitted by the user will be
- appended to the args separated by a blank. The exec must be able to
- deal with this.
-
- REXX Execs must be in a PDS allocated to DD GGEXEC. This ddname
- needs to be allocated in the Gopher server's JCL. For local mode,
- the GOPHER command will allocate the GGEXEC file to the REXX exec
- library specified on the "localexec:" line in your GOPHERRC file,
- if you have activated it. Otherwise you will not be able to use
- REXX execs in local mode.
-
- Note that you do not need the /* REXX */ comment at the beginning of
- REXX execs used by gopher (though it does not hurt to include it!)
- because they are invoked by the IRXEXEC facility and not the standard
- TSO CLIST/EXEC search.
-
- Now, how does the REXX exec return data to the Gopher server?
-
- First of all, it depends on the TYPE that the exec is expected
- to return, which has nothing to do with HOW the returning is done.
-
- So, first let's talk about how the exec returns data, and then
- about what it is expected to return.
-
- How to return data
-
- The REXX exec must return data by writing it to the SYSTSPRT DD.
- Note that this is where normal TSO output goes when a REXX exec
- is run in TSO batch. However, since REXX execs are invoked by
- the IRXEXEC interface by the Gopher server, to prevent dependency
- on a TSO environment, this default behavior of REXX/TSO cannot
- be relied upon. Therefore, if you write a REXX exec to return
- Gopher data, you must explicitly send the output to the SYSTSPRT
- ddname. The Gopher server makes sure that it can read this data.
-
- A typical approach is to queue all the output to the REXX data stack,
- queue a final "" and then use EXECIO. Be careful not to queue null
- lines in this case. Be sure to protect the stack in case of lossage.
- Example:
-
- "NEWSTACK"
- do while more_data_to_get
- some_data = get_some_data()
- if some_data = "" then queue " "
- else queue some_data
- end
- queue ""
- "EXECIO * DISKW SYSTSPRT (FINIS)"
- "DELSTACK"
-
- You can also create a stem variable to hold the output, if you
- want to avoid problems with null lines or nested stacks. Example:
-
- do i = 1 to whatever
- foo.i = get_some_data()
- end
- foo.0 = i
- "EXECIO * DISKW SYSTSPRT (FINIS STEM FOO.)"
-
- A downside is that if the REXX exec finds anomalous conditions
- or executes a TSO command that barfs, standard TSO command output
- will probably get lost. Therefore, try to use OUTTRAP to capture
- command output and test for error codes, and write all captured
- output or error messages to SYSTSPRT in such a way as to allow
- the client to see them (but not treat them as normal directory
- data or whatever).
-
- A helpful hack is to use an EXECUTE exec to invoke other REXX
- code or TSO commands that normally output via PUTLINE. e.g.:
-
- /* REXX. Usage: EXECUTE exec args... */
-
- parse arg real_exec_command
- parse source sourceline
- if word(sourceline,7) = "TSO" then do
- x = outtrap("LINE.")
- real_exec_command
- arc = rc
- x = outtrap("OFF")
- "EXECIO * DISKW SYSTSPRT (FINIS STEM LINE.)"
- end
- else do
- real_exec_command
- arc = rc
- end
-
- return arc
-
- I don't recommend this, though, because it's SLOW.
-
-
- If the Gopher server is a TSO-in-batch job (i.e. EXEC PGM=IKJEFT01)
- then you can issue TSO commands from the exec. To get the output,
- though, you need to use OUTTRAP around them. If they issue TPUT's,
- you are SOL. If they are PL/1 programs that write to SYSPRINT, or
- FORTRAN or assembler, etc., allocate the SYSPRINT or FT06F001 or
- whatever file to a temporary and copy the temporary to SYSTSPRT. If
- it is a C/370 program that writes to stdout or stderr, you may be able
- to use redirection:
-
- CALL 'THEIR.LOAD(CPROG)' 'args > DD:SYSTSPRT'
-
- for stdout
-
- CALL 'THEIR.LOAD(CPROG)' 'args 2> DD:SYSTSPRT'
-
- for stderr
-
- (for multiple output, use >> instead of >)
-
- If gopher server is run straight batch rather than as a TSO job, then
- you cannot run REXX execs that require a TSO environment.
-
- One more important word: Make sure that your SYSTSPRT file has a
- large enough LRECL to handle the REXX output. If it is too short,
- the REXX output will get folded. For TYPE=DIRECTORY in particular,
- this is disastrous. Recommended JCL for executing the Gopher server
- may be found elsewhere in the installation materials, or your MVS
- system programmer has probably already installed a Gopher server in
- 'SYS1.PROCLIB' or the equivalent with the correct allocation.
-
- What it is expected to return
-
- OK - now the good stuff. This depends on the TYPE on the menu entry
- that your exec is trying to fulfill. Some gopher protocol basics:
-
- A Gopher menu is really a text representation of the actual protocol,
- which goes like this:
-
- filetype -tab- name -tab- path -tab- host -tab- port
-
- where -tab- is the EBCDIC (on MVS) or ASCII (on other box) tab
- character, and filetype is a single character. The filetypes
- supported by the MVS Gopher server are:
-
- 0 - flat file
- 1 - directory
- 2 - error
- 7 - index
- 8 - TELNET
- w - whois (experimental)
-
- To generate the equivalent of a Gopher menu, you must output data
- in the above format. Now for the details...
-
- TYPE=FILE
-
- Just return the straight data. Try to avoid null lines because C/370
- believes they don't exist and will throw them away. We hate this, but
- IBM is so hard to convince of reality sometimes... Change all null
- lines to lines containing one blank as you write them out (you need to
- do this anyway if you are queueing output on the stack for EXECIO) and
- you will have no problems.
-
- TYPE=DIRECTORY
-
- You must return lines that fit the gopher protocol format as above.
-
- For example, if you want to generate a Gopher menu on the fly that
- is equivalent to this:
-
- type=file
- name=This is my description
- path=some.gopher.path
- host=sun1.sanjuan.com
- port=70
-
- then you output a line that looks like this:
-
- 0This is my description!some.gopher.path!sun1.sanjuan.com!70
-
- (each ! is really a tab (EBCDIC hex 05) character)
-
- where "0" is the type (file in this example, but would be "1" for
- type=directory, "7" for typeindex, etc.)
-
- Here's the REXX code that might do this:
-
- name = "This is my description"
- path = "some.gopher.path"
- host = "sun1.sanjuan.com"
- tab = '05'x
- port = 70
-
- queue "0"||name||tab||path||tab||host||tab||port
-
- Assuming we write the queued lines to DD SYSTSPRT, as described.
-
- Specifying the Right Host Name
-
- Most of the time you will probably want to generate a menu item
- that points back to your MVS host, not some other host. It may
- even redrive your selfsame REXX exec with new arguments. And if
- the exec was invoked in local (serverless) mode, you want the item
- to get driven in the same mode, probably.
-
- The question is - what's the easiest way to identify what
- the "same server" is? One way is to hardcode the server name (e.g.
- "MVS.DRAPER.COM"), but this is not sufficiently general because:
-
- (1) the server name or location may change
- (2) you can't distribute the exec to other Gopher users
- (3) it won't work the same way in "local mode"
-
- So, you need a way to know what the name of your selfsame host is.
- The MVS Gopher server can use HOST=+, but you can't, as that isn't
- part of the Gopher protocol. So what do you do?
-
- Recommendation: call a function hostname() to return the current
- host name. So in the above code segment, you might have:
-
- host = hostname()
-
- What is that hostname() function anyway?
- Well, you create it.
- Take your Gopher exec library (please) and include an exec
- called HOSTNAME, which you set up to return the name
- of the host that you want to be the "same host".
-
- Note that a plus sign "+" will not work in this context.
- The plus sign is a hack interpreted by the Gopher server
- when it sees it on a menu. It is *not* part of the Gopher
- protocol and therefore cannot be sent over.
-
- However, the minus sign "-" will work, as the Gopher client
- in local mode will interpret it at the protocol level
- (which DOES NOT IMPLY THAT IT IS A PART OF THE STANDARD
- GOPHER PROTOCOL, PROPOSED OR OTHERWISE - THIS IS JUST A
- LOCAL HACK MODIFICATION).
-
- Anyhow, what you ought to do is to have different Gopher
- exec libraries for local (i.e.private) use and public
- server use. The public server will have a HOSTNAME member
- that says
-
- return "MVS.DRAPER.COM"
-
- or whatever the name of *YOUR* gopher server host is.
-
- Your private exec library should have a HOSTNAME member
- that says
-
- return "-"
-
- This is the best I can come up with right now. A future enhancement
- may be to pass the hostname as the second arg to the REXX exec using
- the IRXEXEC interface, e.g.
-
- parse arg execargs, hostname
-
- Then we could pass even more such arguments, like port, etc.
- But that's all for now...
-
-
- ./ ADD NAME=ABOUTCX,SSI=01000051
- This text has not been written yet.
- ./ ADD NAME=ABOUTS,SSI=01040038
- gopher_menu
-
- TYPE=FILE
- NAME=Creating MVS Gopher Menus
- PATH=(ABOUTCSM)
- HOST=+
- END
-
- TYPE=FILE
- NAME=MVS Gopher Access Table
- PATH=(ABOUTSA)
- HOST=+
- END
-
- TYPE=FILE
- NAME=REXX Exec Interface
- PATH=(ABOUTCSX)
- HOST=+
- END
-
- ./ ADD NAME=ABOUTSA,SSI=01020004
-
- Format of entries in the Gopher Access Table:
-
- filename (fully qualified, all uppercase, no quotes)
- can be "DD:DDNAME" or "EXEC:EXECNAME"
-
- followed by names of hosts which are authorized to access the data.
- If no host name list is present, all hosts are authorized
-
- You may specify the same file name more than once, if you need
- more lines to put host names on.
-
- Individual PDS members must be specified separately. A PDS without
- a member name establishes access only to the PDS directory.
-
- Note that the default directory MUST be in this table.
-
- Also note that in the case of EXECs, the EXEC must live in the
- library allocated to GGEXEC in the Gopher server JCL.
-
- *** ANY DATA SET REFERENCED BY ANY EXEC IN THAT LIBRARY IS FULLY
- *** ACCESSIBLE TO GOPHER REGARDLESS OF THIS TABLE! USE THIS TABLE
- *** TO GOVERN CONTROL TO THE EXEC ITSELF!!!
-
- ./ ADD NAME=ABOUTW,SSI=01020053
- What is Gopher?
-
- For more information, read the FAQ, posted to USENET newsgroups
- comp.infosystems.gopher and news.answers every two weeks.
-
- The information contained here is borrowed therefrom in large part.
-
- Gopher is a client/server protocol for building a distributed
- information delivery service. While providing a delivery vehicle for
- local information, Gopher also facilitates access to other Gopher and
- information servers on the Internet.
-
- Gopher servers and clients can be obtained via anonymous ftp to
- boombox.micro.umn.edu. Look in the directory /pub/gopher.
-
- There are clients for the following systems. For the latest
- directory information, see the FAQ.
-
- Unix Curses & Emacs
- Xwindows
- Macintosh Hypercard
- Macintosh Application
- DOS w/Clarkson Driver
- NeXTstep
- VM/CMS
- VMS
- MVS
-
- There are also a number of public telnet login sites available.
- See the FAQ for more information.
-
- There are servers for the following systems. For the latest
- directory information, see the FAQ.
-
- Unix
- VMS
- Macintosh
- VM/CMS
- MVS
-
-
- Papers and articles describing Gopher:
-
- _The_Internet_Gopher_, "ConneXions", July 1992, Interop.
-
- _Exploring_Internet_GopherSpace_ "The Internet Society News", v1n2 1992,
-
- _The_Internet_Gopher_Protocol_, Proceedings of the Twenty-Third
- IETF, CNRI, Section 5.3
-
- _Internet_Gopher_, Proceedings of Canadian Networking '92
-
- _The_Internet_Gopher_, INTERNET: Getting Started, SRI
- International, Section 10.5.5
-
- _Tools_help_Internet_users_discover_on-line_treasures, Computerworld,
- July 20, 1992
-
- Gopher will also be in two forthcoming O'Reilly Books:
- "Administrating TCP/IP, and The Whole Internet"
-
- ./ ADD NAME=FAQ,SSI=01020044
- Xref: news.draper.com comp.infosystems.gopher:886 news.answers:2444
- Newsgroups: comp.infosystems.gopher,news.answers
- From: gopher@boombox.micro.umn.edu (UofMN Gopher Team)
- Subject: Gopher (comp.infosystems.gopher) Frequently Asked Questions (FAQ)
- Followup-To: comp.infosystems.gopher
- Summary: Common Questions and Answers about the Internet Gopher, a
- client/server protocol for making a world wide information
- service, with many implementations.
- Sender: news@news2.cis.umn.edu (Usenet News Administration)
- Organization: University of Minnesota
- Date: Thu, 5 Nov 1992 21:29:00 GMT
-
- Archive-name: gopher-faq
- Last-modified: 1992/10/29
-
- Common Questions and Answers about the Internet Gopher, a
- client/server protocol for making a world wide information service,
- with many implementations. Posted to comp.infosystems.gopher and
- news.answers every two weeks.
-
- The most recent version of this FAQ can be gotten through gopher, or
- via anonymous ftp:
-
- pit-manager.mit.edu:/pub/usenet/news.answers/gopher-faq
-
- Those without FTP access should send e-mail to mail-server@rtfm.mit.edu
- with "send usenet/news.answers/finding-sources" in the body to find out
- how to do FTP by e-mail.
-
-
-
- -------------------------------------------------------------------
- Q0: What is Gopher?
-
- A0: The Internet Gopher client/server provides a distributed
- information delivery system around which a world/campus-wide
- information system (CWIS) can readily be constructed. While
- providing a delivery vehicle for local information, Gopher
- facilitates access to other Gopher and information servers
- throughout the world.
-
- -------------------------------------------------------------------
- Q1: Where can I get gopher?
-
- A1: via anonymous ftp to boombox.micro.umn.edu. Look in the directory
- /pub/gopher
-
- --------------------------------------------------------------------
- Q2: What do I need to access gopher?
-
- A2: You will need a gopher "client" program that runs on your local PC
- or workstation
-
- There are clients for the following systems. The directory
- following the name is the location of the client on the anonymous
- ftp site boombox.micro.umn.edu (134.84.132.2) in the directory
- /pub/gopher.
-
- Unix Curses & Emacs : /pub/gopher/Unix/gopher1.03.tar.Z
- Xwindows : /pub/gopher/Unix/xgopher1.1a.tar.Z
- Macintosh Hypercard : /pub/gopher/Mac_client/
- Macintosh Application : /pub/gopher/Macintosh-TurboGopher
- DOS w/Clarkson Driver : /pub/gopher/PC_client/
- NeXTstep : /pub/gopher/NeXT/
- VM/CMS : /pub/gopher/Rice_CMS/ or /pub/gopher/Vienna_CMS/
- VMS : /pub/gopher/VMS/
- OS/2 2.0 : /pub/gopher/os2/
- MVS/XA : /pub/gopher/mvs
-
- A Macintosh application, MacGopher is available via anonymous ftp
- from ftp.cc.utah.edu:
-
- Macintosh Application : /pub/gopher/Macintosh
-
- Another Macintosh application, "GopherApp" is available via
- anonymous ftp from ftp.bio.indiana.edu:
-
- Macintosh Application : /util/gopher/gopherapp
-
- A port of the UNIX curses client for DOS with PC/TCP is available
- via anonymous ftp from oac.hsc.uth.tmc.edu:
-
- DOS w/ PC/TCP : /public/dos/misc/dosgofer.exe
-
- A port of the UNIX curses client for PC-NFS is available via
- anonymous ftp from bcm.tmc.edu:
-
- DOS w/ PC-NFS : /nfs/gopher.exe
-
- A beta version of the PC Gopher client for Novell's LAN Workplace
- for DOS is available from lennon.itn.med.umich.edu
-
- LWP for DOS : /gopher
-
-
- All of the above clients can also be fetched via a gopher client
- itself. Put the following on a gopher server:
-
- Type=1
- Host=boombox.micro.umn.edu
- Port=70
- Path=
- Name=Gopher Software Distribution.
-
-
- Or point your gopher client at boombox.micro.umn.edu, port 70 and
- look in the gopher directory.
-
- There are also a number of public telnet login sites available.
- The University of Minnesota operates one on the machine
- "consultant.micro.umn.edu" (134.84.132.4) See Q3 for more
- information about this. It is recommended that you run the client
- software instead of logging into the public telnet login sites. A
- client uses the custom features of the local machine (mouse,
- scroll bars, etc.) A local client is also faster.
-
- ---------------------------------------------------------------------
- Q3: Where are there publicly available logins for gopher.
-
- A3: Here is a short list, use the site closest to you to minimize
- network lag.
-
- Non-tn3270 Public Logins:
-
- Hostname IP# Login Area
- ------------------------- --------------- ------ -------------
- consultant.micro.umn.edu 134.84.132.4 gopher North America
- gopher.uiuc.edu 128.174.33.160 gopher North America
- panda.uiowa.edu 128.255.40.201 panda North America
- gopher.sunet.se 192.36.125.2 gopher Europe
- info.anu.edu.au 150.203.84.20 info Australia
- gopher.chalmers.se 129.16.221.40 gopher Sweden
- tolten.puc.cl 146.155.1.16 gopher South America
- ecnet.ec 157.100.45.2 gopher Ecuador
-
- tn3270 Public Logins:
-
- Hostname IP# Login Area
- ------------------------- --------------- ------ -------------
- pubinfo.ais.umn.edu 128.101.109.1 -none- North America
-
-
- It is recommended that you run the client software instead of
- logging into the public login sites. A client uses the
- custom features of the local machine (mouse, scroll bars, etc.)
- and is local client is also faster.
-
- ---------------------------------------------------------------------
- Q4: How can I add to the information in gopher?
-
- A4: You can do this by running a gopher server. Servers are available
- for a number of systems. Use anonymous ftp to
- boombox.micro.umn.edu (134.84.132.2) and look in /pub/gopher. The
- following servers are available there:
-
- Unix : /pub/gopher/Unix/gopherxx.tar.Z
- VMS : /pub/gopher/VMS/
- Macintosh : /pub/gopher/Mac_server/
- VM/CMS : /pub/gopher/Rice_CMS/ or /pub/gopher/Vienna_CMS/
- MVS : /pub/gopher/mvs/
- DOS PC : /pub/gopher/PC_server/
-
-
- When you have your server ready you can publish it to the world by
- sending e-mail to the maintainters of the "Other gophers" list:
-
- gopher@boombox.micro.umn.edu
-
- ---------------------------------------------------------------------
- Q5: Who Develops Gopher Software?
-
- A5: Gopher was originally developed in April 1991 by the University
- of Minnesota Microcomputer, Workstation, Networks Center to help
- our campus find answers to their computer questions.
-
- It has since grown into a full-fledged World Wide Information
- System used by a large number of sites in the world.
-
- Many people have contributed to the project, too numerous to
- count.
-
- The people behind the much of the gopher software can be reached
- via e-mail at gopher@boombox.micro.umn.edu, or via paper mail:
-
- Internet Gopher Developers
- 100 Union St. SE #190
- Minneapolis, MN 55455 USA
-
- ---------------------------------------------------------------------
- Q6: How can I set up a "CSO" phone book server? Where is the software?
-
- A6: CSO phone book servers are also known as "qi" servers. The
- software implementation can be gotten via anonymous ftp from
- uxc.cso.uiuc.edu (128.174.5.50) as /pub/qi.tar.Z. You may also
- see this referred to as "ph", which is what most of the clients
- are called.
-
- There is also an archive of the mailing list for qi/ph software on
- the same machine. It's in /pub/info-ph.archive.
-
- This software is supported by Steve Dorner <s-dorner@uiuc.edu>
- Contact him for more information.
-
- -------------------------------------------------------------------
- Q7: Why can't I access the University of Minnesota's UPI news?
-
- A7: The University of Minnesota has a site license for UPI news, we
- are not allowed to distribute it off of our campus. We get our
- UPI news from Clarinet. For more information about getting UPI
- news send mail to info@clarinet.com. For information about
- setting up your own gopher-UPI server search the gopher-news
- archive for UPI.
-
- -------------------------------------------------------------------
- Q9: What are the type characters for the different Gopher Objects?
-
- A9: Normal IDs.
-
- 0 Item is a file
- 1 Item is a directory
- 2 Item is a CSO (qi) phone-book server
- 3 Error
- 4 Item is a BinHexed Macintosh file.
- 5 Item is DOS binary archive of some sort.
- 6 Item is a UNIX uuencoded file.
- 7 Item is an Index-Search server.
- 8 Item points to a text-based telnet session.
- 9 Item is a binary file! Client must read until the connection
- closes. Beware.
- T TN3270 connection.
-
- Experimental IDs.
-
- s Sound type. Data stream is a mulaw sound.
- g GIF type.
- M MIME type. Item contains MIME data.
- h html type.
- I Image type.
- i "inline" text type (used by panda).
-
- -------------------------------------------------------------------
- Q10: When I do full-text searches I always get every document back, Why?
-
- A10: This is a problem occasionally encountered with Unix full-text
- indexes. It is caused by setting up the link incorrectly to a
- gindexd port.
-
- The Path= field should be *blank* when pointing to a gindexd
- index.
-
- Otherwise the client will send the path to the gindexd daemon,
- which interprets everything as a keyword. This path is
- likely to contain a pathname that is common to all of the indexed
- files. Thus a search generates hits on everything.
-
- -------------------------------------------------------------------
- Q11: When I try to build the UNIX software I get an error from make:
- "Must be a separator on rules line #. Stop" Why?
-
- A11: This is a problem with older makes that don't understand the "include"
- keyword. One easy way to cope with this problem is compiling GNU
- make, which does understand the include keyword.
-
- If this is too difficult, remove the line:
-
- include Makefile.config
-
- from all the Makefiles and paste in a copy of Makefile.config at
- the top of each Makefile.
-
- Or, instead of pasting you can make the client/server by going
- into the appropriate directory and typing:
-
- make -f ../Makefile.config -f Makefile
-
- -------------------------------------------------------------------
- Q12: What is the relationship between Gopher and (WAIS, WWW, ftp)?
-
- A12: Gopher is intimately intertwined with these two other systems.
- As shipped the Unix gopher server has the capability to:
-
- - Search local WAIS indices.
- - Query remote WAIS servers and funnel the results to gopher
- clients.
- - Query remote ftp sites and funnel the results to gopher
- clients.
- - Be queried by WWW (World Wide Web) clients (either using
- built in gopher querying or using native http querying.
-
- -------------------------------------------------------------------
- Q13: Are papers or articles describing gopher available?
-
- A13: Gopher has a whole chapter devoted to it in :
-
- _The_Whole_Internet_, Ed Kroll, O'Reilly, 1992 (Editors note:
- ..Great book, go out and buy a bunch!)
-
- Other references include:
-
- _The_Internet_Gopher_, "ConneXions", July 1992, Interop.
-
- _Exploring_Internet_GopherSpace_ "The Internet Society News", v1n2 1992,
-
- (You can subscribe to the Internet Society News by sending e-mail to
- isoc@nri.reston.va.us)
-
- _The_Internet_Gopher_Protocol_, Proceedings of the Twenty-Third
- IETF, CNRI, Section 5.3
-
- _Internet_Gopher_, Proceedings of Canadian Networking '92
-
- _The_Internet_Gopher_, INTERNET: Getting Started, SRI
- International, Section 10.5.5
-
- _Tools_help_Internet_users_discover_on-line_treasures, Computerworld,
- July 20, 1992
-
- _TCP/IP_Network_Administration_, O'Reilly.
-
- Balakrishan, B. (Oct 1992)
- "SPIGopher: Making SPIRES databases accessible through the
- Gopher protocol". SPIRES Fall '92 Workshop, Chapel Hill, North
- Carolina.
-
- -------------------------------------------------------------------
- Q14: On a DECstation I get the error message "/etc/svc.conf no such file
- or directory" when running the gopherd server, why?
-
- A14: This is caused by the chroot() call in gopherd. It can be easily
- fixed by running gopherd with the -c option.
-
- Alternatively you can copy /etc/svc.conf into a directory named
- "etc" inside the gopher-data directory.
- -------------------------------------------------------------------
- Q15: The boolean searching terms don't work for my full-text index, why?
-
- A15: This is probably because the searching is being provided by WAIS.
- WAIS opts to return all documents that contain a search phrase
- within certain limits. WAIS searches do return the documents with
- the highest "score" at the top, those documents will have the
- closest relevance.
- -------------------------------------------------------------------
- Q16: When linking the Unix gopher server with WAIS I get undefined symbols,
- such as:
-
- log_file_name
- logfile
- PrintStatus
- find_value
- Sources
- NumSources
-
- A17: This happens if you make gopherd before linking in the WAIS ir/ui
- directories. The fix is to "make clean" or remove
- gopherd/{waisgopher.o,Waisindex.o} and then remake gopherd. Or
- link the ir/ui directories first.
- -------------------------------------------------------------------
- Q18: Why don't my WAIS indexes work? I never get anything back for searches.
- or Why do I get "Dangling file" error messages in my logfile?
-
- A18: The problem could be in the server. The server should be run
- using the -c option if you want WAIS to work. Another solution is to
- patch the WAIS code so that it doesn't check the files on the disk.
- Search the gopher-news archive for "dangling". This will turn up a
- single document with the patch.
-
- -------------------------------------------------------------------
- Q19: My gopher server doesn't work under inetd, why?
-
- A19: It could be that your inetd server only supports a limited amount
- of arguments. For instance, the maximum number of arguments to an
- inetd server is 5. You can get around this by combining arguments: i.e.
-
- gopherd -I -c
-
- becomes:
-
- gopherd -Ic
-
- You may also leave the port specifier off of the command line.
- The gopher server automagically finds out the port it's running on.
-
- -------------------------------------------------------------------
- Q20: This is not a bug report, just a curiousity. I managed to install
- gopher on my PC, more or less by myself, which is a pretty good
- accomplishment, for someone who hasn't installed hardly anything on a
- PC. I then proceeded to load my PC/TCP kernel, ETHDRV, and try to
- start up gopher. It said it couldn't initialize that stack(?). I have
- to load this whenever I use PC/TCP. Incredibly, when I did not load
- ETHDRV, Gopher came up immediately and telneted to our local server.
- How does it know what kernel to load?
-
- A20 Dr. Science says,
-
- The Internet Gopher program is not actually computer program at
- all, but a collection of magical incantations handed down from Dark
- Age conjurors. It works by sending magical "demons" through the air,
- which scour the world for information, and then return to cast
- illusions containing the answer.
-
- When you use the Gopher, your computer isn't actually doing
- anything at all. Instead, these demons have mesmirized you with an
- evil magical spell, which was invoked by the pattern of
- finger-movements peculiar to the typing of the letters G-O-P-H-E-R on
- your keyboard. This spell transmits demonic information directly to
- your brain.
-
- Scientists aren't certain of the long-term effects of demonic
- mesmirization, although former presidents have suffered only minor
- medical side-effects from it. Indeed, since Magic and Science are
- usually opposed to each other, most Scientists are usually
- close-minded about such issues, and will usually respond with some
- vacuous non-answer about "packet drivers", "stacks", and other such
- jargon.
-
- Unlike conventional scientists, Dr. Science is very open-minded and
- is willing to deal with such issues in a frank and honest manner.
- This is why people come to him with questions, and why they've learned
- to rely on and live by his answers.
-
- Dr. Science
- "I'm not a real doctor; I have a Master's Degree.... in SCIENCE!"
-
- :-) :-) :-) :-)
- There's always room for a little humor in a FAQ..
- -------------------------------------------------------------------
- Q21: Help! I have PC-NFS and want to use the PC-Gopher client. How?
-
- A21: Use a piece of software called PKTMUX, available at fine ftp
- sites everywhere. This will let you use any packet driver
- application.
-
- Or, aquire a client that supports PC-NFS. See Q2.
- -------------------------------------------------------------------
- Q22: How do I nuke a hung TCP connection? I can't restart my UNIX
- gopher server unless I get rid of it, and I don't want to reboot!
-
- A22:
-
- Here is an example of using dbx to change a socket from CLOSING to
- CLOSED.
-
- # netstat -A|grep CLOSING
- c4bc5100 tcp 0 11 mymachine.gopher 129.89.8.4.70 CLOSING
- # dbx -k /vmunix /dev/mem
- ...
- (dbx) 0xc4bc5100+8/1X -- display contents of PCB+8
- c4bc5108: 00000007
- (dbx) assign 0xc4bc5108=0 -- zero it
- 0
- (dbx) q
-
- After a minute or two, the CLOSED socket should disappear.
- -------------------------------------------------------------------
- Q23: Is there somewhere I can retrieve a list of announced gopher
- links? I'd like to keep a local, up-to-date list of available gopher
- holes without requiring our users to gopher to umn just to scan
- GopherSpace.
-
- A23: In the Unix client/server distribution is a perl script called
- "gopherdist". Gopherdist can fetch the contents of any point in
- GopherSpace.
-
- To dump the contents of all the North American links from
- gopher.tc.umn.edu do the following:
-
- % gopherdist gopher.tc.umn.edu 70 "1/Other Gopher and Information
- Servers/North America" > .Links
- --
- | Paul Lindner | lindner@boombox.micro.umn.edu | Slipping into madness
- | | Computer & Information Services | is good for the sake
- | Gophermaster | University of Minnesota | of comparision.
- ///// / / / /////// / / / / / / / / //// / / / / / / / /
-
-
- ./ ENDUP
- ?!
- //C EXEC GGLOAD,TRK1='14',TO='C'
- //SYSIN DD DATA,DLM='?!'
- ./ ADD NAME=GGCLIENT,SSI=01180054
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #ifdef SASC
- #pragma runopts(EXECOPS)
- #else
- #pragma runopts(heap(8k,8k,anywhere,))
- #pragma runopts(nospie,nostae)
- #endif
-
- #pragma csect(code, "GG@LIENT")
- #pragma csect(static,"GG$LIENT")
- #include "gg.h"
-
- /*********************************************************************/
-
- static char copyright_notice[] =
- "Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 \n\
- \n\
- GOPHER server due to Shawn Hart at the University of Delaware. \n\
- \n\
- This software is provided on an 'AS IS' basis. All warranties, \n\
- including the implied warranties of merchantability and fitness,\n\
- are expressly denied. \n\
- \n\
- Provided this copyright notice is included, this software may \n\
- be freely distributed and not offered for sale. \n\
- \n\
- Changes or modifications may be made and used only by the maker \n\
- of same, and not further distributed. Such modifications should\n\
- be mailed to the author for consideration for addition to the \n\
- software and incorporation in subsequent releases.";
-
- /*********************************************************************/
-
- #ifdef I370
- char * _style = "tso:";
- #endif
-
- /*********************************************************************/
-
- static Bool
- go_for_it(gp,ip)
- struct ggcb *gp;
- struct gopherinfo *ip;
- {
- char temp [32];
-
- (void)GGMivget(gp,"GGHOST ",ip->host,sizeof(ip->host));
- (void)GGMivget(gp,"GGPATH ",ip->path,sizeof(ip->path));
- (void)GGMivget(gp,"GGDESC ",ip->desc,sizeof(ip->desc));
- (void)GGMivget(gp,"GGPORT ",temp ,sizeof(temp) );
- ip->type = INITIAL_TYPE;
- if (!*ip->path) strcpy(ip->path,INITIAL_PATH);
- if (!*ip->host) strcpy(ip->host,INITIAL_HOST);
- if (!*ip->desc) strcpy(ip->desc,INITIAL_DESC);
- ip->port = atoi(temp);
- if (ip->port == 0) ip->port = INITIAL_PORT;
-
- return GGMgofor(gp,ip,FALSE);
-
- }
-
- /*********************************************************************/
-
- int
- main(argc,argv)
- int argc;
- char **argv;
-
- {
- struct ggcb *gp;
- struct gopherinfo *ip;
- char *p;
- int i;
- int exit_return_code;
- Bool bypass_startup;
- struct ggcb gg;
- char zerrsm [25];
- char zerrlm [73];
-
- exit_return_code = 0;
-
- memset(&gg,0,sizeof(struct ggcb));
-
- gp = ≫
-
- /* set up top-level gopherinfo structure */
-
- GETMAIN(ip, struct gopherinfo, 1, "top-level gopherinfo struct");
- if (!ip) {
- fprintf(stderr,"Not enough memory to start up GOPHER\n");
- exit(16);
- }
-
- memset(ip,0,sizeof(struct gopherinfo));
-
- gp->ginfo = ip;
-
- gp->test_mode = FALSE;
- gp->debug_mode = FALSE;
- gp->local_mode = FALSE;
- bypass_startup = FALSE;
-
- for (i = 1; i < argc; i++) {
- p = argv[i];
- if (*p == '-') {
- while (*++p) {
- switch (toupper(*p)) {
- case 'T': gp->test_mode = TRUE; break;
- case 'D': gp->debug_mode = TRUE; break;
- case 'L': gp->local_mode = TRUE; break;
- case 'Q': bypass_startup = TRUE; break;
- default: fprintf(stderr,"GGMVS: Bad parameter flag %c\n", *p);
- exit_return_code = 8;
- }
- }
- }
- else {
- fprintf(stderr,"GGMVS: Bad parameter string %s\n",p);
- exit_return_code = 8;
- }
- }
-
- if (gp->test_mode) __ctest(NULL);
-
- if (gp->debug_mode) {
- if (!(gp->debug_file = fopen("dd:ggdebug","w"))) {
- perror("debug file (DD GGDEBUG)");
- exit_return_code = 4;
- }
- }
- else gp->debug_file = NULL;
-
- gp->thdr.first_text_line = NULL;
-
- GGMclrtx(gp,NULL); /* Clear text */
- GGMclrtx(gp,ip); /* Clear text */
-
- gp->g_bytes_returned = 0;
- gp->g_buf_index = -1;
-
- /* Determine the local path name. Done in GGMCONN when needed now */
-
- strcpy(gp->ggserver,"");
- gp->connected_to_server = FALSE;
- gp->closing_connection = FALSE;
- gp->reconnect_in_progress = FALSE;
- gp->receiving_text = FALSE;
-
- GETMAIN(gp->server_buf, char,SERVER_BUF_MSGSIZE+4,"server buffer");
- GETMAIN(gp->client_buf, char,CLIENT_BUF_MSGSIZE+4,"client buffer");
- GETMAIN(gp->gopher_command,char,CLIENT_BUF_MSGSIZE+4,"gopher command");
-
- #ifdef FETCH
-
- gp->isplink_pointer = (int (*) ())fetch("ISPLINK");
- gp->ispexec_pointer = (int (*) ())fetch("ISPEXEC");
-
- #endif
-
- if (!GGMispf(gp,"CONTROL ERRORS RETURN")) exit_return_code = 20;
-
- else {
-
- exit_return_code = 0;
-
- /* not done yet: set up command and selection code tables */
-
- GGMsopt(gp,OPTION_ALL); /* set options */
-
- if (bypass_startup) {
- (void)GGMispf(gp,"VGET (GGHOST GGPATH GGDESC GGPORT) PROFILE");
- (void)go_for_it(gp,ip);
- }
- else {
- (void)GGMivput(gp,"ZCMD " ,"",-1);
- while (GGMdispl(gp,"GGM ") == 0
- && !gp->quit
- && !go_for_it(gp,ip)) ;
- }
- }
-
- if (gp->setmsg) {
- (void)GGMivget(gp,"ZERRSM ",zerrsm, sizeof(zerrsm));
- (void)GGMivget(gp,"ZERRLM ",zerrlm, sizeof(zerrlm));
- fprintf(stderr,"%s: %s\n",zerrsm,zerrlm);
- gp->setmsg = FALSE;
- }
-
- if (gp->connected_to_server) {
- GGMdisc(gp); /* disconnect from news server */
- }
-
- FREEMAIN(gp->gopher_command,"gopher command");
- FREEMAIN(gp->server_buf, "server buffer");
- FREEMAIN(gp->client_buf, "client buffer");
- FREEMAIN(gp->ginfo, "top-level gopherinfo struct");
-
- #define FINAL_CLOSE(A,B) \
- if (A) { \
- if (fclose(A) < 0) fprintf(stderr,B); \
- }
-
- FINAL_CLOSE(gp->debug_file, "Error closing debug file\n");
-
- exit(exit_return_code);
- }
-
- ./ ADD NAME=GGMALLOC,SSI=01030039
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@ALLOC")
- #pragma csect(static,"GG$ALLOC")
- #include "gg.h"
-
- /****** Allocate a data set. *****************************************/
-
- enum data_set_type
- GGMalloc(dsname,ddname,wanted_type,nitems)
- char *dsname;
- char *ddname;
- enum data_set_type wanted_type;
- int nitems;
- {
- int i;
- int rc;
- char *cp;
- enum data_set_type return_type;
- Bool try_new;
- short primary_allocation ;
- short secondary_allocation ;
- short directory_blocks ;
- short dsorg ;
- __S99parms stuff99; /* No "struct", despite manual */
- TEXTUNIT *tu [17];
- TEXTUNIT tu_dsn;
- TEXTUNIT tu_ddn;
- TEXTUNIT tu_member;
- TEXTUNIT tu_stat;
- TEXTUNIT tu_disp;
- TEXTUNIT tu_perm;
- TEXTUNIT tu_rtddn;
- TEXTUNIT tu_rtorg;
- TEXTUNIT tu_block;
- TEXTUNIT tu_prime;
- TEXTUNIT tu_sec;
- TEXTUNIT tu_dir;
- TEXTUNIT tu_recfm;
- TEXTUNIT tu_lrecl;
- TEXTUNIT tu_blksz;
- TEXTUNIT tu_dsorg;
- char *lparp;
- char *rparp;
- char dsnseq [81];
- char member [81];
- char what_to_open[81];
- FILE *mfile;
-
- try_new = FALSE;
-
- memset((char *)&stuff99,0,sizeof(__S99parms));
-
- strcpy(member,"");
- strcpy(dsnseq,dsname);
- lparp = strchr(dsnseq,'(');
- rparp = strchr(dsnseq,')');
- if (lparp && rparp && (lparp < rparp) && (*(rparp+1) == '\0')) {
- *lparp = '\0'; /* makes dsnseq the seq part only */
- *rparp = '\0'; /* turns member into a string */
- strcpy(member, lparp+1);
- wanted_type = PDS;
- }
-
- for (;;) {
-
- stuff99.__S99RBLN = 20;
- stuff99.__S99VERB = S99VRBAL;
- stuff99.__S99FLAG1 = S99NOCNV << 8;
- stuff99.__S99ERROR = 0;
- stuff99.__S99INFO = 0;
- stuff99.__S99TXTPP = tu;
- stuff99.__S99FLAG2 = 0;
-
- i = 0;
-
- tu[i++] = &tu_dsn;
-
- tu_dsn.key = DALDSNAM;
- tu_dsn.num = 1;
- tu_dsn.ent.len = strlen(dsnseq);
- strcpy(tu_dsn.ent.prm,dsnseq);
- for (cp=tu_dsn.ent.prm; *cp; cp++) *cp = toupper(*cp);
-
- tu[i++] = &tu_stat;
-
- tu_stat.key = DALSTATS;
- tu_stat.num = 1;
- tu_stat.ent.len = 1;
- *tu_stat.ent.prm = (try_new ? NEW : SHR);
-
- tu[i++] = &tu_disp;
-
- tu_disp.key = DALNDISP;
- tu_disp.num = 1;
- tu_disp.ent.len = 1;
- *tu_disp.ent.prm = (try_new ? CATLG : KEEP);
-
- tu[i++] = &tu_rtorg;
-
- tu_rtorg.key = DALRTORG;
- tu_rtorg.num = 1;
- tu_rtorg.ent.len = 2;
-
- if (*member) {
-
- tu[i++] = &tu_member;
-
- tu_member.key = DALMEMBR;
- tu_member.num = 1;
- tu_member.ent.len = strlen(member);
- strcpy(tu_member.ent.prm,member);
- for (cp=tu_member.ent.prm; *cp; cp++) *cp = toupper(*cp);
-
- }
-
- if (ddname && *ddname) {
-
- tu[i++] = &tu_ddn;
-
- tu_ddn.key = DALDDNAM;
- tu_ddn.num = 1;
- tu_ddn.ent.len = strlen(ddname);
- strcpy(tu_ddn.ent.prm,ddname);
- for (cp=tu_ddn.ent.prm; *cp; cp++) *cp = toupper(*cp);
-
- tu[i++] = &tu_perm;
-
- tu_perm.key = DALPERMA;
- tu_perm.num = 0;
- }
- else {
-
- tu[i++] = &tu_rtddn;
-
- tu_rtddn.key = DALRTDDN;
- tu_rtddn.num = 1;
- tu_rtddn.ent.len = 8;
- memset(tu_rtddn.ent.prm,' ',8);
-
- }
-
- if (try_new) {
-
- switch (wanted_type) {
- case PDS:
- primary_allocation = (short)nitems;
- secondary_allocation = primary_allocation;
- directory_blocks = ((short)nitems/(12*36)+1) * 36;
- dsorg = DSORG_PO;
- break;
- case SEQ:
- default:
- primary_allocation = (short)nitems;
- secondary_allocation = primary_allocation;
- directory_blocks = 0;
- dsorg = DSORG_PS;
- break;
- }
-
- tu[i++] = &tu_block;
-
- tu_block.key = DALBLKLN;
- tu_block.num = 1;
- tu_block.ent.len = 3;
- memset(tu_block.ent.prm,0,3);
- *(short *)(tu_block.ent.prm+1) = 6233;
-
- tu[i++] = &tu_prime;
-
- tu_prime.key = DALPRIME;
- tu_prime.num = 1;
- tu_prime.ent.len = 3;
- memset(tu_prime.ent.prm,0,3);
- *(short *)(tu_prime.ent.prm+1) = primary_allocation;
-
- tu[i++] = &tu_sec;
-
- tu_sec.key = DALSECND;
- tu_sec.num = 1;
- tu_sec.ent.len = 3;
- memset(tu_sec.ent.prm,0,3);
- *(short *)(tu_sec.ent.prm+1) = secondary_allocation;
-
- tu[i++] = &tu_dir;
-
- tu_dir.key = DALDIR;
- tu_dir.num = 1;
- tu_dir.ent.len = 3;
- memset(tu_dir.ent.prm,0,3);
- *(short *)(tu_dir.ent.prm+1) = directory_blocks;
-
- tu[i++] = &tu_recfm;
-
- tu_recfm.key = DALRECFM;
- tu_recfm.num = 1;
- tu_recfm.ent.len = 1;
- *tu_recfm.ent.prm = RECFM_VB;
-
- tu[i++] = &tu_lrecl;
-
- tu_lrecl.key = DALLRECL;
- tu_lrecl.num = 1;
- tu_lrecl.ent.len = 2;
- *(short *)tu_lrecl.ent.prm = 259;
-
- tu[i++] = &tu_blksz;
-
- tu_blksz.key = DALBLKSZ;
- tu_blksz.num = 1;
- tu_blksz.ent.len = 2;
- *(short *)tu_blksz.ent.prm = 6233;
-
- tu[i++] = &tu_dsorg;
-
- tu_dsorg.key = DALDSORG;
- tu_dsorg.num = 1;
- tu_dsorg.ent.len = 2;
- *(short *)tu_dsorg.ent.prm = dsorg;
-
- }
-
- tu[i] = (void *)0x80000000;
-
- rc = svc99(&stuff99);
-
- if (rc == 0) {
- if (!(ddname && *ddname)) {
- memcpy(ddname,(char *)tu_rtddn.ent.prm,8);
- *(ddname+8) = ' ';
- *(strchr(ddname,' ')) = '\0';
- }
- switch (tu_rtorg.ent.prm[0]) {
- case 0x40: return_type = SEQ; break;
- case 0x02: return_type = PDS; break;
- default: return_type = UNK; break;
- }
- if (wanted_type == SEQ && return_type != SEQ) {
- fprintf(stderr,"%s: not a sequential data set\n",dsname);
- }
- if (wanted_type == PDS && return_type != PDS) {
- fprintf(stderr,"%s: not a partitioned data set\n",dsname);
- }
- if (return_type == PDS && *member) return SEQ;
- else return return_type;
- }
- else if (!try_new && nitems != 0 && stuff99.__S99ERROR == 0x1708) {
- try_new = TRUE;
- continue;
- }
- else {
- GGMdfail(rc,&stuff99);
- return UNK;
- }
- }
- }
-
- ./ ADD NAME=GGMBRIFC,SSI=01020028
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@BRIFC")
- #pragma csect(static,"GG$BRIFC")
- #include "gg.h"
-
- /****** BRIF primary command function. *******************************/
-
- int
- GGMbrifc(numptr,dialog_data_ptr)
- int *numptr;
- void *dialog_data_ptr;
- {
- Rstruc ggcb *gp = *(Rstruc ggcb **)dialog_data_ptr;
- Rstruc gopherinfo *ip = gp->ginfo;
- struct gopherinfo *ip1;
- char zcmd[80];
- char command[80];
- char operand[80];
- char *p;
- int opoff;
-
- /*
- * For commands which are supposed to terminate the current BRIF
- * (like NEXT and PREV), we return an invalid return code, which
- * is documented to make BRIF itself return with a code of 16,
- * which we treat as a normal end.
- */
-
- (void)GGMivget(gp,"ZCMD ",zcmd,sizeof(zcmd));
- strcpy(command,"");
- strcpy(operand,"");
- if (1 <= sscanf(zcmd,"%s %n",&command,&opoff)) {
- for (p=command;*p;p++) *p = toupper(*p);
- if ((EQUAL(command,"EXTRACT") || EQUAL(command,"EXT"))) {
- if (!ip) (void)GGMivput(gp,"GGTNUM ","",-1);
- gp->extract_file = NULL;
- (void)GGMispf(gp,"CONTROL DISPLAY SAVE");
- (void)GGMxtx(gp,ip); /* Extract text */
- (void)GGMispf(gp,"CONTROL DISPLAY RESTORE");
- return 0;
- }
- else
- if (EQUAL(command,"PRT")) {
- (void)GGMispf(gp,"CONTROL DISPLAY SAVE");
- GGMptx(gp,ip); /* Print text */
- (void)GGMispf(gp,"CONTROL DISPLAY RESTORE");
- return 0;
- }
- else
- if (EQUAL(command,"QUIT")) {
- gp->quit = TRUE;
- return 1;
- }
- else {
- ERR1(
- "The only non-BROWSE commands available are EXTract and PRT."
- );
- return 12;
- }
- }
-
- return 4; /* ISPF-PDF should handle the command */
-
- }
-
- ./ ADD NAME=GGMBRIFR,SSI=01000032
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@BRIFR")
- #pragma csect(static,"GG$BRIFR")
- #include "gg.h"
-
- /****** BRIF read function. ******************************************/
-
- int
- GGMbrifr(dataptr,lenptr,recnoptr,dialog_data_ptr)
- char **dataptr;
- int *lenptr;
- int *recnoptr;
- void *dialog_data_ptr;
- {
- Rstruc textline *tp;
- Rstruc ggcb *gp;
- Rstruc texthdr *thp;
- int return_value;
- int current_recno;
- int i;
-
- gp = *(struct ggcb **)dialog_data_ptr;
- thp = gp->brifp;
- current_recno = *recnoptr;
- return_value = 0;
- tp = NULL;
-
- if (current_recno == 99999999) { /* scroll down max request */
- tp = NULL;
- }
- else if (thp->current_text_line != NULL &&
- current_recno == gp->brif_previous_recno+1) {
- tp = thp->current_text_line->next;
- while (tp && tp->text_length < 0) tp = tp->next;
- }
- else {
- for (i = 0, tp = thp->first_text_line; tp; tp = tp->next) {
- if (tp->text_length >= 0) {
- if (++i >= current_recno) break;
- }
- }
- }
-
- if (tp == NULL) {
- *recnoptr = thp->text_line_count;
- return_value = 8;
- }
- else {
- thp->current_text_line = tp;
- *dataptr = tp->tab_expanded_text;
- *lenptr = tp->tab_expanded_text_length;
- return_value = 0;
- }
-
- gp->brif_previous_recno = current_recno;
-
- return return_value;
-
- }
-
- ./ ADD NAME=GGMCLRTX,SSI=01000031
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@CLRTX")
- #pragma csect(static,"GG$CLRTX")
- #include "gg.h"
-
- /****** Clear text. **************************************************/
-
- void
- GGMclrtx(gp,ip)
- Rstruc ggcb *gp;
- Rstruc gopherinfo *ip;
-
- {
- Rstruc texthdr *thp;
- Rstruc textline *tp1;
- Rstruc textline *tp2;
-
- /* If info is not specified, use main ggcb, else info's text */
-
- thp = (ip ? &ip->thdr : &gp->thdr);
-
- tp1=thp->first_text_line;
- while (tp1) {
- tp2 = tp1->next;
- FREEMAIN(tp1,"text line");
- tp1 = tp2;
- }
-
- thp->text_body_line = NULL;
- thp->first_text_line = NULL;
- thp->current_text_line = NULL;
- thp->last_text_line = NULL;
- thp->text_line_count = 0;
- thp->text_max_length = 0;
- thp->text_max_tab_expanded_length = 0;
-
- return;
-
- }
-
- ./ ADD NAME=GGMCONN,SSI=010D0008
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@CONN ")
- #pragma csect(static,"GG$CONN ")
- #include "gg.h"
-
- /****** Internet address formatter. **********************************/
-
- static void
- format_ip_address(ia,is)
- IPADDRESS ia;
- char *is;
- {
- char *cp = (char *)&ia;
-
- sprintf(is,"%d.%d.%d.%d",*cp,*(cp+1),*(cp+2),*(cp+3));
- return;
- }
-
- /****** Get client hostname and IP address. **************************/
-
- static Bool
- get_client_hostname(gp)
- Rstruc ggcb *gp;
- {
- struct hostent *client_hp;
- int gethostnamerc;
- int hostlen;
- int domslen;
-
- gethostnamerc = gethostname(gp->client_hostname,MAXHOSTNAMELEN);
- if (gethostnamerc < 0) {
- fprintf(stderr,"GGMVS: gethostname() failed, don't know my name\n");
- return FALSE;
- }
-
- #ifdef APPEND_DOMAIN_NAME_TO_SELF
-
- hostlen = strlen(gp->client_hostname);
- domslen = sizeof(MY_DOMAIN_SUFFIX) - 1;
- if (hostlen <= domslen ||
- memcmp(gp->client_hostname+hostlen-domslen,
- MY_DOMAIN_SUFFIX, domslen)) {
- strncat(gp->client_hostname,MY_DOMAIN_SUFFIX,domslen);
- }
-
- #endif
-
- uppercase_in_place(gp->client_hostname);
-
- client_hp = gethostbyname(gp->client_hostname);
- if (!client_hp) {
- fprintf(stderr,"GGMVS: gethostbyname() failed, can't get my name\n");
- return FALSE;
- }
-
- strcpy(gp->ggclient,gp->client_hostname);
- strcpy(gp->client_hostname, client_hp->h_name);
- gp->client_ip_address = *(IPADDRESS *)client_hp->h_addr;
-
- return TRUE ;
-
- }
-
- /****** Connect to news server. **************************************/
-
- Bool
- GGMconn(gp)
- Rstruc ggcb *gp;
- {
- char *lp;
- char *cp;
- struct recvstruct *R;
- struct hostent *server_hp;
- struct sockaddr_in bindsock; /* socket used by bind */
- struct sockaddr_in consock; /* socket used by connect */
- int bindsocklen; /* size of bind socket */
- int consocklen; /* size of connect socket */
- int bindrc; /* the return code from bind */
- int connrc; /* the return code from connect */
- int ip_part_1;
- int ip_part_2;
- int ip_part_3;
- int ip_part_4;
- char tempdsn[L_tmpnam];
-
- if (gp->connected_to_server) {
- GGMdisc(gp); /* Disconnect from news server */
- }
-
- gp->closing_connection = FALSE;
-
- if (!*gp->ggserver) {
- ERR1(
- "No host server defined in Gopher menu, Cannot make a connection."
- );
- return FALSE;
- }
-
- uppercase_in_place(gp->ggserver);
-
- /* If server is "local hack", then establish local mode,
- * open temporary file and return.
- */
-
- if (!strcmp(gp->ggserver, LOCAL_HOST_FROB)) {
-
- if (gp->ginfo->port != GOPHER_PORT_NUMBER) {
- ERR3("Server name %s is permitted only with port number %d.",
- LOCAL_HOST_FROB, GOPHER_PORT_NUMBER);
- return FALSE;
- }
-
- GETMAIN(gp->recvp,struct recvstruct, 1, "local recv struct");
- if (!gp->recvp) {
- CRIT1("Can't get memory for local host struct");
- return FALSE;
- }
- R = gp->recvp;
- memset(R,0,sizeof(struct recvstruct));
-
- if (!tmpnam(tempdsn)) {
- CRIT1("Can't create temporary file for local access");
- return FALSE;
- }
-
- /* Create temporary file for writing and reading. */
-
- R->outfp = fopen(tempdsn,"w+,type=memory");
- if (!R->outfp) {
- perror(tempdsn);
- CRIT1("Can't open temporary file for local access");
- return FALSE;
- }
-
- gp->connected_to_server = TRUE;
- gp->time_to_go_home = FALSE;
- gp->connection_broken = FALSE;
-
- GGMesrvr(gp);
-
- return TRUE;
- }
-
- /* Disallow network connections if started up in local mode. */
-
- if (gp->local_mode) {
- ERR1("Network connections are not allowed in local mode.");
- return FALSE;
- }
-
- /* Determine the local path name. Do only if making net conn. */
-
- if (!*gp->client_hostname) {
-
- if (!get_client_hostname(gp)) return FALSE;
-
- }
-
- /* Get server name and address. */
-
- if (strchr(gp->ggserver,'.') &&
- gp->ggserver[strspn(gp->ggserver,".0123456789")] == '\0') {
- ip_part_1 = ip_part_2 = ip_part_3 = ip_part_4 = 32767;
- strcpy(gp->server_hostname, gp->ggserver);
- sscanf(gp->ggserver,"%d.%d.%d.%d",&ip_part_1,
- &ip_part_2,
- &ip_part_3,
- &ip_part_4);
- if (ip_part_1 > 255 ||
- ip_part_2 > 255 ||
- ip_part_3 > 255 ||
- ip_part_4 > 255) {
- ERR2("Syntax error in server network address: %s", gp->ggserver);
- return FALSE;
- }
- gp->server_ip_address = (IPADDRESS) ((ip_part_1 << 24) +
- (ip_part_2 << 16) +
- (ip_part_3 << 8) +
- (ip_part_4 ));
- }
- else {
- server_hp = gethostbyname(gp->ggserver);
- if (!server_hp) {
- ERR2(
- "Unknown host %s - gethostbyname() could not resolve the server name.",
- gp->ggserver);
- return FALSE;
- }
- strcpy(gp->server_hostname, server_hp->h_name);
- gp->server_ip_address = *(IPADDRESS *)server_hp->h_addr;
- }
-
- format_ip_address(gp->server_ip_address, gp->server_ip_addrstr);
- format_ip_address(gp->client_ip_address, gp->client_ip_addrstr);
-
- (void)GGMivput(gp,"GGSERVER ",gp->ggserver,-1);
- (void)GGMivput(gp,"GGSERVIP ",gp->server_ip_addrstr,-1);
- (void)GGMivput(gp,"GGCLIENT ",gp->ggclient,-1);
- (void)GGMivput(gp,"GGCLIEIP ",gp->client_ip_addrstr,-1);
-
- consock.sin_family = AF_INET;
- consock.sin_port = htons(gp->ginfo->port);
- consock.sin_addr.s_addr = gp->server_ip_address;
-
- bindsock.sin_family = AF_INET;
- bindsock.sin_port = 0;
- #ifdef SNSTCPIP
- bindsock.sin_addr.s_addr = INADDR_ANY;
- #else
- bindsock.sin_addr.s_addr = gp->client_ip_address;
- #endif
-
- gp->socknum = socket(AF_INET, SOCK_STREAM, 0);
- if (gp->socknum < 0) {
- REPORT_TCP_ERROR(gp->ggserver);
- ERR2("TCP/IP error: socket() failed to make socket for server %s.",
- gp->ggserver);
- return FALSE;
- }
-
- bindsocklen = sizeof(bindsock);
- bindrc = Bind(gp->socknum, &bindsock, bindsocklen);
- if (bindrc < 0) {
- REPORT_TCP_ERROR(gp->ggserver);
- ERR2("TCP/IP error: bind() failed to bind socket for server %s.",
- gp->ggserver);
- return FALSE;
- }
-
- (void)GGMispf(gp,"CONTROL DISPLAY LOCK");
- (void)GGMispf(gp,"DISPLAY PANEL(GGMLCONN)");
-
- if (gp->debug_file) {
- fprintf(gp->debug_file,
- "Client %s (%s) connecting to GOPHER server on %s (%s)\n",
- gp->client_hostname,
- gp->client_ip_addrstr,
- gp->server_hostname,
- gp->server_ip_addrstr);
- }
-
- consocklen = sizeof(consock);
- connrc = Connect(gp->socknum, &consock, consocklen);
-
- if (connrc < 0) {
- REPORT_TCP_ERROR(gp->ggserver);
- ERR2("TCP/IP failure: connect() failed to connect to server %s.",
- gp->ggserver);
- return FALSE;
- }
-
- gp->connected_to_server = TRUE;
- gp->time_to_go_home = FALSE;
- gp->connection_broken = FALSE;
-
- /* Clean up any stray responses from server. */
-
- GGMesrvr(gp); /* End server read */
-
- return TRUE;
-
- }
-
- ./ ADD NAME=GGMCSO,SSI=01000040
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@CSO")
- #pragma csect(static,"GG$CSO")
- #include "gg.h"
-
- /****** Gopher CSO interface. ************************************/
-
- Bool
- GGMcso(gp,ip,as_file)
- Rstruc ggcb *gp;
- Rstruc gopherinfo *ip;
- Fool as_file; /* ignored */
- {
- char *lp;
- Bool got_some;
- char ggcsoq[256];
- int e_index_i;
- char e_index_c[10];
- char sep[80] =
- "--------------------";
-
- strcpy(gp->ggserver,ip->host); /* Specify server to connect to */
-
- strcpy(ggcsoq,"");
-
- GGMispf(gp,"VGET (GGCSOQ) PROFILE");
-
- if (GGMdispl(gp,"GGMPCSO ") > 0) return FALSE;
-
- GGMivget(gp,"GGCSOQ ",ggcsoq, sizeof(ggcsoq));
-
- /***** set up query command to server ****** start ******************/
-
- strcpy(gp->gopher_command,"query ");
- if (!*ip->path)
- strcpy(gp->gopher_command + 6, ggcsoq);
- else
- sprintf(gp->gopher_command + 6,"%s\t%s",ip->path,ggcsoq);
- strcat(gp->gopher_command," return all");
-
- /***** set up query command to server ****** end ******************/
-
- gp->ginfo = ip;
- gp->receiving_text = FALSE;
-
- if (!GGMconn(gp)) return FALSE; /* Connect to gopher server */
-
- if (!GGMsockt(gp)) return FALSE; /* Send socket command to server */
-
- GGMclrtx(gp,ip); /* Clear text */
-
- gp->receiving_text = TRUE;
- got_some = FALSE;
- e_index_i = 2;
- sprintf(e_index_c,":%u:",e_index_i);
- do {
- if (GGMgsrvl(gp,&lp,FALSE)) { /* Get server line */
- if (lp) {
- if (strstr(lp,e_index_c) != NULL) { /* if new entry */
- (void)GGMouttx(gp,sep,ip); /* Output separator */
- ++e_index_i; /* Increment index */
- sprintf(e_index_c,":%u:",e_index_i);
- }
- got_some = TRUE;
- (void)GGMouttx(gp,lp,ip); /* Output text line */
- if (lp[0] != '-' && strncmp(lp,"200",3) >= 0) break;
- }
- }
- } while (lp); /* until no more lines */
-
- if (!got_some) {
- WARN2("No data available from server %s.\n",gp->ggserver);
- return FALSE;
- }
-
- /* Send quit command */
-
- gp->receiving_text = FALSE;
-
- strcpy(gp->gopher_command,"quit");
-
- if (!GGMsockt(gp)) return FALSE; /* Send socket command to server */
-
- /* Read Bye message */
-
- gp->receiving_text = TRUE;
-
- (void)GGMgsrvl(gp,&lp,FALSE); /* Get server line */
-
- if (gp->connected_to_server) {
- (void)GGMdisc(gp); /* Disconnect from gopher server */
- }
-
- GGMvtx(gp,ip,as_file); /* display text from CSO server */
-
- return TRUE;
-
- }
-
- ./ ADD NAME=GGMDFAIL,SSI=01000005
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@DFAIL")
- #pragma csect(static,"GG$DFAIL")
- #include "gg.h"
-
- /****** Retrieve allocation failure messages. ************************/
-
- void
- GGMdfail(rc,p99)
- int rc;
- __S99parms *p99;
- {
- int zero = 0;
- unsigned int dfid = 0x40320000;
- struct {
- short first_level_msg_len;
- short first_level_msg_offset;
- char first_level_msg[251];
- short second_level_msg_len;
- short second_level_msg_offset;
- char second_level_msg[251];
- } dfbuffer;
-
- static int (*ikjeff18_pointer)() = NULL;
-
- #ifndef FETCH
- extern int *ikjeff18();
- #endif
-
- if (!ikjeff18_pointer) {
- #ifdef FETCH
- ikjeff18_pointer = (int (*)())fetch("IKJEFF18");
- #else
- ikjeff18_pointer = (int (*)())ikjeff18;
- #endif
- }
-
- dfbuffer.first_level_msg_len = 4;
- dfbuffer.second_level_msg_len = 4;
-
- if (ikjeff18_pointer) {
- if ((*ikjeff18_pointer)(p99,&rc,&zero,&dfid,&zero,&dfbuffer)) {
- fprintf(stderr,"IKJEFF18 returned a nonzero return code\n");
- }
- if (dfbuffer.first_level_msg_len > 0) {
- fprintf(stderr,"%*.*s\n",
- dfbuffer.first_level_msg_len-4,
- dfbuffer.first_level_msg_len-4,
- dfbuffer.first_level_msg);
- }
- if (dfbuffer.second_level_msg_len > 0) {
- fprintf(stderr,"%*.*s\n",
- dfbuffer.second_level_msg_len-4,
- dfbuffer.second_level_msg_len-4,
- dfbuffer.second_level_msg);
- }
- }
- else {
- #ifdef FETCH
- fprintf(stderr,"GGMVS: Cannot fetch IKJEFF18\n");
- #else
- fprintf(stderr,"Cannot call IKJEFF18, not linked with GGMVS\n");
- #endif
- }
- return;
- }
-
- ./ ADD NAME=GGMDIR,SSI=012B0041
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@DIR ")
- #pragma csect(static,"GG$DIR ")
- #include "gg.h"
-
- /*********************************************************************/
-
- static Bool
- valid_code(c)
- char c;
- {
-
- switch (c) {
- case GOPHER_FILE:
- case GOPHER_DIRECTORY:
- case GOPHER_TELNET:
- case GOPHER_TN3270:
- case GOPHER_WAIS:
- case GOPHER_WHOIS:
- case GOPHER_CSO:
- return TRUE;
- default: return FALSE;
- }
-
- }
-
- /*********************************************************************/
-
- static Bool
- process_s_selection(gp,ip)
- Rstruc ggcb *gp;
- Rstruc gopherinfo *ip;
- {
-
- GGMgofor(gp,ip,FALSE);
-
- return TRUE;
- }
-
- /*********************************************************************/
-
- static Bool
- process_e_selection(gp,ip)
- Rstruc ggcb *gp;
- Rstruc gopherinfo *ip;
- {
-
- if (ip->thdr.first_text_line) {
- GGMxtx(gp,ip);
- return TRUE;
- }
- else {
- ERR1("Extract must be preceded by Select.");
- return FALSE;
- }
- }
-
- /*********************************************************************/
-
- static Bool
- process_q_selection(gp,ip)
- Rstruc ggcb *gp;
- Rstruc gopherinfo *ip;
- {
-
- GGMgofor(gp,ip,TRUE);
-
- return TRUE;
- }
-
- /*********************************************************************/
-
- static Bool
- display_dynamic_area(gp,ip,infoarray,entrycount)
- Rstruc ggcb *gp;
- Rstruc gopherinfo *ip;
- Rstruc gopherinfo *infoarray;
- int entrycount;
- {
- struct gopherinfo *iap;
- int depth;
- int ggglvl;
- int dynsize;
- int topitem;
- int bottomitem;
- int last_item_selected;
- int dti;
- int gii;
- int l;
- int prc;
- int command_index;
- int zscrolln;
- Bool selection_processed_ok;
- Bool command_processed_ok;
- Bool is_max;
- char *gggdyna;
- char *rowp;
- char *cp;
- char gggcmd [72];
- char zverb [9];
- char zscrolla [9];
- char command [COMMANDSIZE];
- char ggghead [81];
- char rowmessage [81];
-
- /* Get depth of dynamic area (number of rows to display on screen) */
-
- (void)GGMispf(gp,
- "PQUERY PANEL(GGMDIR) AREANAME(GGGDYNA) DEPTH(GGGDEPTH)");
- if (gp->ispfrc != 0) return FALSE;
- depth = GGMiget(gp,"GGGDEPTH ");
-
- /* Get storage for ISPF dynamic area variable to be constructed. */
-
- dynsize = 80*depth;
- GETMAIN(gggdyna, char, dynsize+1, "GGGDYNA buffer");
- if (!gggdyna) return FALSE;
-
- /* Loop displaying the panel until END pressed. */
-
- topitem = 0;
- last_item_selected = -1;
- strcpy(gggcmd,"");
-
- do {
-
- /* Fill in the dynamic area with rows, one for each gopher item. */
-
- memset(gggdyna,' ',dynsize);
-
- for (dti = 0, gii = topitem, rowp = gggdyna;
- dti < depth && gii < entrycount;
- dti++, gii++, rowp += 80) {
- iap = &infoarray[gii];
- rowp[ 0] = DATAIN_HIGH; /* selection code attribute */
- rowp[ 1] = ' '; /* selection code field */
- rowp[ 2] = DATAOUT_GREEN; /* icon attribute */
- memcpy(&rowp[ 3],GGMtype(iap->type),9);
- rowp[12] = DATAOUT_HIGH; /* description attribute */
- l = strlen(iap->desc);
- memcpy(&rowp[13],iap->desc,l > 67 ? 67 : l);
- }
-
- if (rowp < gggdyna + dynsize) {
- rowp[0] = DATAOUT_HIGH;
- memset(&rowp[1], '-',79);
- }
-
- bottomitem = gii - 1;
-
- if (topitem > bottomitem) strcpy(rowmessage,"");
- else sprintf(rowmessage, " %d-%d of %d",
- topitem + 1, bottomitem + 1, entrycount);
-
- memset(ggghead,' ',79);
- ggghead[79] = '\0';
- strcpy(ggghead,"GOPHER - ");
- strncpy(ggghead+9,ip->desc,70);
- *strchr(ggghead,'\0') = ' ';
- memcpy(ggghead+79-strlen(rowmessage),rowmessage,strlen(rowmessage));
-
- (void)GGMivput(gp,"GGGHEAD ",ggghead,79);
- (void)GGMivput(gp,"GGGDYNA ",gggdyna, dynsize);
- (void)GGMivput(gp,"GGGCMD " ,gggcmd, -1);
-
- prc = GGMdispl(gp,"GGMDIR ");
- if (prc > 8) break;
-
- (void)GGMivget(gp,"GGGDYNA " , gggdyna, dynsize);
- (void)GGMivget(gp,"ZVERB " , zverb, sizeof(zverb));
- (void)GGMivget(gp,"ZSCROLLA ", zscrolla, sizeof(zscrolla));
- zscrolln = GGMiget(gp,"ZSCROLLN ");
- ggglvl = GGMiget(gp,"GGGLVL ");
- last_item_selected = -1;
-
- /* Process selections. */
-
- for (gii = topitem, rowp = gggdyna;
- gii <= bottomitem;
- gii++, rowp += 80) {
- iap = &infoarray[gii];
- switch (rowp[1]) {
- case ' ': continue;
- case 's':
- case 'S': selection_processed_ok = process_s_selection(gp,iap);
- break;
- case 'e':
- case 'E': selection_processed_ok = process_e_selection(gp,iap);
- break;
- case 'q':
- case 'Q': selection_processed_ok = process_q_selection(gp,iap);
- break;
- default:
- ERR1("Unknown selection code. Type one of the listed codes.");
- selection_processed_ok = FALSE;
- break;
- }
- if (selection_processed_ok) last_item_selected = gii;
- if (gp->quit) break;
- }
-
- /* Process command if any. */
-
- strcpy(gggcmd,"");
-
- (void)GGMivget(gp,"GGGCMD ",gggcmd,sizeof(gggcmd));
-
- if (*gggcmd) {
-
- memset(command,' ',COMMANDSIZE);
- command_index = 0;
- for (cp = gggcmd; *cp && !isspace(*cp); cp++) {
- if (cp >= gggcmd+COMMANDSIZE) {
- ERR1("Invalid command name.");
- command_processed_ok = FALSE;
- }
- command[command_index++] = toupper(*cp);
- }
- while (*cp && isspace(*cp)) cp++;
-
- if (memcmp(command,"QUIT ",8) == 0) {
- gp->quit = TRUE;
- }
- else {
- ERR2("Unknown command name: %8.8s",command);
- }
- command_processed_ok = FALSE;
-
- if (command_processed_ok) strcpy(gggcmd,"");
-
- }
-
- if (gp->quit) break;
-
- if (last_item_selected >= 0 && gp->autoscroll) {
- topitem = last_item_selected;
- }
-
- /* Process scroll request if any. */
-
- is_max = EQUAL(zscrolla,"MAX");
- if (EQUAL(zverb,"DOWN")) {
- if (is_max) topitem = entrycount - ggglvl;
- else topitem += zscrolln;
- }
- else if (EQUAL(zverb,"UP")) {
- if (is_max) topitem = 0;
- else topitem -= zscrolln;
- }
- else if (EQUAL(zverb,"RETURN")) {
- gp->quit = TRUE;
- break;
- }
- if (topitem < 0)
- topitem = 0;
- if (topitem > entrycount)
- topitem = entrycount;
-
- } while (prc == 0);
-
- return;
-
- }
-
- /****** Gopher a directory. ******************************************/
-
- Bool
- GGMdir(gp,ip,as_file)
- Rstruc ggcb *gp;
- Rstruc gopherinfo *ip;
- Fool as_file;
- {
- int entrycount;
- int i;
- int copysize;
- char typechar;
- char savechar;
- char *p;
- char *q;
- char *r;
- struct textline *tp;
- struct gopherinfo *infoarray;
- struct gopherinfo *iap;
- char temp[16];
-
- if (as_file) {
- GGMvtx(gp,ip,as_file); /* if as a file, display text as is */
- return TRUE;
- }
-
- /* The text chain contains the data from the server, which should be
- * in the following format:
- *
- * nDescription^Path^foo^bar
- *
- * where the "n" in the beginning is a digit and ^ means a tab char.
- *
- * Logic:
- *
- * Build an array of gopherinfo structs from the text records.
- *
- * Display them as an ISPF dynamic area pseudotable.
- *
- * Let the user select them, and run GGMgofor on each one
- * with a struct gopherinfo built from the contents.
- *
- */
-
- /* Determine size of array of gopherinfo structs. This is equal to
- * the number of text records with a valid code in the first byte.
- */
-
- entrycount = 0;
- for (tp = ip->thdr.first_text_line; tp; tp = tp->next) {
- if (valid_code(tp->text[0])) entrycount++;
- }
-
- if (entrycount == 0) {
- ERR1("There seems to be no information in this directory.\n");
- return FALSE;
- }
-
- /* Allocate an array of structs to hold the stuff. */
-
- GETMAIN(infoarray, struct gopherinfo, entrycount,"gopherinfo array");
-
- if (!infoarray) {
- ERR2("Not enough memory for %d gopher directory entries\n",
- entrycount);
- return FALSE;
- }
-
- /* Build the array entries. */
-
- iap = infoarray;
- for (tp = ip->thdr.first_text_line; tp; tp = tp->next) {
- typechar = tp->text[0];
- if (valid_code(typechar)) {
- r = &tp->text[tp->text_length];
- savechar = *r;
- *r = '\t';
- memset(iap,0,sizeof(struct gopherinfo));
- iap->port = GOPHER_PORT_NUMBER;
- iap->type = (gophertype)typechar;
- p = &tp->text[1];
- q = strchr(p,'\t');
- copysize = sizeof(iap->desc)-1;
- if (copysize > q-p) copysize = q-p;
- memcpy(iap->desc,p,copysize);
- if (q < r) {
- p = q+1;
- q = strchr(p,'\t');
- copysize = sizeof(iap->path)-1;
- if (copysize > q-p) copysize = q-p;
- memcpy(iap->path,p,copysize);
- if (q < r) {
- p = q+1;
- q = strchr(p,'\t');
- copysize = sizeof(iap->host)-1;
- if (copysize > q-p) copysize = q-p;
- memcpy(iap->host,p,copysize);
- if (q < r) {
- p = q+1;
- q = strchr(p,'\t');
- memset(temp,0,sizeof(temp));
- copysize = sizeof(temp)-1;
- if (copysize > q-p) copysize = q-p;
- memcpy(temp,p,copysize);
- iap->port = atoi(temp);
- }
- }
- }
- *r = savechar;
- iap++;
- }
- }
-
- if (gp->debug_mode) {
- for (iap = infoarray, i = entrycount; i > 0; iap++, i--) {
- fprintf(gp->debug_file,"GGMdir: type = %d\n",iap->type);
- fprintf(gp->debug_file,"GGMdir: port = %d\n",iap->port);
- fprintf(gp->debug_file,"GGMdir: path = %s\n",iap->path);
- fprintf(gp->debug_file,"GGMdir: host = %s\n",iap->host);
- fprintf(gp->debug_file,"GGMdir: desc = %s\n",iap->desc);
- fprintf(gp->debug_file,"\n");
- }
- }
-
- display_dynamic_area(gp,ip,infoarray,entrycount);
-
- FREEMAIN(infoarray,"gopherinfo array");
-
- return TRUE;
- }
-
- ./ ADD NAME=GGMDISC,SSI=01050033
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@DISC ")
- #pragma csect(static,"GG$DISC ")
- #include "gg.h"
-
- /****** Disconnect from gopher server. ********************************/
-
- void
- GGMdisc(gp)
- Rstruc ggcb *gp;
- {
- int closerc;
- struct recvstruct *R;
-
- /* If local mode, close temporary file and return. */
-
- if ((R=gp->recvp)) {
- if (R->outfp) {
- if (fclose(R->outfp) < 0) {
- CRIT1("Error closing local mode temporary file");
- }
- R->outfp = NULL;
- }
-
- gp->connected_to_server = FALSE;
-
- FREEMAIN(gp->recvp,"local mode recv struct");
- gp->recvp = NULL;
- return;
- }
-
- gp->reconnect_in_progress = FALSE;
- gp->closing_connection = TRUE;
-
- if (gp->connection_broken) {
- if (gp->debug_file) {
- fprintf(gp->debug_file,
- "Client %s (%s) connection with gopher server on %s (%s) was lost\n",
- gp->client_hostname,
- gp->client_ip_addrstr,
- gp->server_hostname,
- gp->server_ip_addrstr);
- }
- gp->connected_to_server = FALSE;
- }
- else {
-
- /* In case of some kind of protocol error, don't let things hang. */
-
- GGMesrvr(gp); /* End server read */
-
- if (gp->debug_file) {
- fprintf(gp->debug_file,
- "Client %s (%s) disconnecting from gopher server on %s (%s)\n",
- gp->client_hostname,
- gp->client_ip_addrstr,
- gp->server_hostname,
- gp->server_ip_addrstr);
- }
-
- (void)GGMivput(gp,"GGSOLDER ",gp->server_hostname,-1);
- (void)GGMivput(gp,"GGSOLDIP ",gp->server_ip_addrstr,-1);
- (void)GGMispf(gp,"CONTROL DISPLAY LOCK");
- (void)GGMispf(gp,"DISPLAY PANEL(GGMLDISC)");
-
- /* In case of some kind of protocol error, don't let things hang. */
-
- GGMesrvr(gp); /* End server read */
-
- gp->connected_to_server = FALSE;
-
- TCP_DEBUG_ON;
- closerc = close(gp->socknum);
- TCP_DEBUG_OFF;
-
- if (closerc < 0) {
- ERR2("TCP/IP error: close() failed to disconnect from server %s.",
- gp->ggserver);
- }
- }
-
- return;
- }
-
- ./ ADD NAME=GGMDISPL,SSI=01010001
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- /********************************************************************/
-
- #pragma csect(code, "GG@DISPL")
- #pragma csect(static,"GG$DISPL")
- #include "gg.h"
-
- #ifdef FETCH
- #define VL_BIT(X) ((unsigned int)(X) | 0x80000000)
- #else
- #define VL_BIT(X) (X)
- #endif
-
- /****** Display ISPF panel. ******************************************/
-
- int
- GGMdispl(gp,pan8)
- Rstruc ggcb *gp;
- char *pan8;
- {
-
- if (gp->setmsg) {
- gp->ispfrc = ISPLINK("DISPLAY ", pan8, VL_BIT("ISRZ002 "));
- }
- else {
- gp->ispfrc = ISPLINK("DISPLAY ", VL_BIT(pan8));
- }
-
- if (gp->ispfrc > 8) GGMierr(gp); /* display ISPF error */
-
- gp->setmsg = FALSE;
-
- return gp->ispfrc;
- }
-
- ./ ADD NAME=GGMDUMP,SSI=01000036
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@DUMP ")
- #pragma csect(static,"GG$DUMP ")
- #include "gg.h"
-
- /****** Dump some data. **********************************************/
-
- void
- GGMdump(struct ggcb *gp, char *label, char *p,int r)
- {
- int i;
-
- if (!gp->debug_file) return;
-
- if (r == -2) {
- fprintf(gp->debug_file,"%s: %d\n",label,(int)p);
- return;
- }
-
- if (r == -1) r = strlen(p);
-
- fprintf(gp->debug_file,"%s: (%d characters)\n",label,r);
- for (i=0;i<77;i++) fprintf(gp->debug_file,"-");
- fprintf(gp->debug_file,"\n");
- for (i=0;i<r;i++) {
- char c = *(p+i);
- if (isprint(c)) fprintf(gp->debug_file,"%c",c);
- else fprintf(gp->debug_file,"<0x%2.2x>",c);
- }
- fprintf(gp->debug_file,"\n");
- for (i=0;i<77;i++) fprintf(gp->debug_file,"-");
- fprintf(gp->debug_file,"\n");
-
- return;
-
- }
-
- ./ ADD NAME=GGMESRVR,SSI=01030044
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@ESRVR")
- #pragma csect(static,"GG$ESRVR")
- #include "gg.h"
-
- /****** End server read. *********************************************/
-
- void
- GGMesrvr(gp)
- Rstruc ggcb *gp;
- {
- char *lp;
- Bool found_more_server_data = FALSE;
-
- GGMclrtx(gp,NULL); /* Clear text */
-
- if (gp->recvp) return; /* Skip if non-socket */
-
- do {
-
- if (GGMgsrvl(gp,&lp,FALSE)) { /* Get server line */
- if (lp) {
- found_more_server_data = TRUE;
- (void)GGMouttx(gp,lp,NULL); /* Output text line */
- }
- }
-
- } while (lp);
-
- if (found_more_server_data) {
- ERR1(
- "More data was returned by the GOPHER server than GOPHER expected."
- );
- GGMvtx(gp,NULL,TRUE); /* View text */
- }
-
- return;
- }
-
- ./ ADD NAME=GGMFREEM,SSI=01000001
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@FREEM")
- #pragma csect(static,"GG$FREEM")
- #include "gg.h"
-
- /****** Free memory. *************************************************/
-
- void
- GGMfreem(gp,stuff,whatfor)
- Rstruc ggcb *gp;
- char *stuff;
- char *whatfor;
- {
-
- free(stuff);
-
- if (gp->debug_file) {
- fprintf(gp->debug_file,"GGMfreem: freed memory for %s\n", whatfor);
- }
- return;
-
- }
-
- ./ ADD NAME=GGMGETDS,SSI=01020011
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- /********************************************************************/
-
- #pragma csect(code, "GG@GETDS")
- #pragma csect(static,"GG$GETDS")
- #include "gg.h"
-
- #define DUMMY_FILE_POINTER_FOR_PDS (FILE *)(-1)
-
- /****** Prompt user for the name of a data set to extract into. ******/
-
- FILE *
- GGMgetds(gp,ep)
- Rstruc ggcb *gp;
- Rstruc extraction *ep;
- {
- FILE *xfp;
- Bool asked_for;
- char ggexdsn[65]; /* data set name for extraction */
- char ggexapp [4]; /* YES or NO for append mode */
- char ggextab [4]; /* YES or NO for tab expansion */
- char ggexblk [4]; /* YES or NO for blank after sep*/
- char ggexsep[81]; /* Separator line (optional) */
- char ggexan1[16]; /* From article number */
- char ggexan2[16]; /* To article number */
- char ggexpmp [9]; /* PDS member name prefix */
- char ddname [9];
- char member [9];
- char pdspec [32];
- char quoted_dsname [67];
- char formatted_number [11];
-
- /* Display panel asking for data set name into which to extract. */
-
- xfp = NULL;
- asked_for = TRUE;
-
- (void)GGMispf(gp,"ADDPOP");
-
- while (xfp == NULL) {
-
- /* Keep asking for a dsname until one works or END pressed. */
-
- if (GGMdispl(gp,ep->panelname) > 0) {
- asked_for = FALSE;
- xfp = NULL;
- break;
- }
-
- (void)GGMivget(gp,"GGEXDSN ",ggexdsn,sizeof(ggexdsn));
- (void)GGMivget(gp,"GGEXTAB ",ggextab,sizeof(ggextab));
- (void)GGMivget(gp,"GGEXAN1 ",ggexan1,sizeof(ggexan1));
- (void)GGMivget(gp,"GGEXAN2 ",ggexan2,sizeof(ggexan2));
- if (ep->mode == PDS) {
- (void)GGMivget(gp,"GGEXPMP ",ggexpmp,sizeof(ggexpmp));
- }
- else {
- (void)GGMivget(gp,"GGEXAPP ",ggexapp,sizeof(ggexapp));
- (void)GGMivget(gp,"GGEXBLK ",ggexblk,sizeof(ggexblk));
- (void)GGMivget(gp,"GGEXSEP ",ggexsep,sizeof(ggexsep));
- }
-
- if (ep->mode == PDS) {
-
- ep->appending = FALSE;
- ep->blanking = FALSE;
- strcpy(ep->separator,"");
- strcpy(ep->ddname,"");
- strcpy(ep->member_prefix,ggexpmp);
-
- /* Note: panel forces fully-qualified name to pass to allocate */
-
- /* check if the PDS already exists */
-
- if (ggexdsn[0] != '\'') {
- strcpy(quoted_dsname,"'");
- strcat(quoted_dsname,ggexdsn);
- strcat(quoted_dsname,"'");
- }
- else strcpy(quoted_dsname,ggexdsn);
-
- /* Check if PDS already exists. */
-
- if (gp->warn_overwrite) {
- xfp = fopen(quoted_dsname,"r");
- if (xfp) {
- (void)fclose(xfp);
- xfp = NULL;
- if (GGMdispl(gp,"GGMPEXPW") > 0) {
- WARN1("Operation cancelled, because you pressed END.");
- break;
- }
- }
- }
-
- if (GGMalloc(ggexdsn,ep->ddname,PDS,ep->count) != PDS) {
- ERR2("Allocation failed for data set %s.", ggexdsn);
- xfp = NULL;
- continue;
- }
- strcpy(ep->dsname, ggexdsn);
- }
- else {
- strcpy(ep->separator, ggexsep);
- strcpy(ep->dsname, ggexdsn);
- ep->appending = (ggexapp[0] == 'Y');
- ep->blanking = (ggexblk[0] == 'Y');
- }
-
- ep->tab_expanding = (ggextab[0] == 'Y');
- if (*ggexan1) ep->from_number = atoi(ggexan1);
- else ep->from_number = 0;
- if (*ggexan2) ep->to_number = atoi(ggexan2);
- else ep->to_number = INT_MAX;
-
- /* check if the dataset already exists */
- /* (Wonder if this will compile. Have fun, "cc"...) */
-
- if (ep->appending ? gp->warn_append : gp->warn_overwrite) {
- xfp = fopen(ggexdsn,"r");
- if (xfp) {
- (void)fclose(xfp);
- xfp = NULL;
- if (GGMdispl(gp,"GGMPEXOW") > 0) {
- WARN1("Operation cancelled, because you pressed END.");
- break;
- }
- }
- }
-
- if (ep->mode == PDS) {
- xfp = DUMMY_FILE_POINTER_FOR_PDS;
- break;
- }
-
- xfp = OPEN_TEXT_FILE_FOR_WRITE_OR_APPEND(ggexdsn,ep->appending);
-
- if (!xfp) {
- perror(ggexdsn);
- ERR2("Cannot open data set %s.", ep->dsname);
- }
- }
-
- (void)GGMispf(gp,"REMPOP");
-
- return xfp;
-
- }
-
- ./ ADD NAME=GGMGETM,SSI=01000052
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@GETM ")
- #pragma csect(static,"GG$GETM ")
- #include "gg.h"
-
- /****** Get memory. **************************************************/
-
- void
- GGMgetm(gp,pointer,howmuch,whatfor)
- Rstruc ggcb *gp;
- char **pointer;
- int howmuch;
- char *whatfor;
- {
-
- *pointer = (char *)malloc(howmuch);
-
- if (*pointer == NULL) {
- fprintf(stderr,"GGMgetm: Cannot obtain %d bytes of memory for %s\n",
- howmuch,whatfor);
- }
- else if (gp->debug_file) {
- fprintf(gp->debug_file,"GGMgetm: got %d bytes of memory for %s\n",
- howmuch,whatfor);
- }
- return;
-
- }
-
- ./ ADD NAME=GGMGOFOR,SSI=011A0004
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@GOFOR")
- #pragma csect(static,"GG$GOFOR")
- #include "gg.h"
-
- /********************************************************************/
-
- static Bool
- connect_to_gopher_server(gp,ip,is_cr_needed)
- Rstruc ggcb *gp;
- Rstruc gopherinfo *ip;
- Fool is_cr_needed;
- {
- char *lp;
- Bool got_some;
-
- strcpy(gp->ggserver,ip->host); /* Specify server to connect to */
- strcpy(gp->gopher_command,ip->path); /* Specify command to issue */
- gp->ginfo = ip;
- gp->receiving_text = FALSE;
-
- if (!GGMconn(gp)) return FALSE; /* Connect to gopher server */
-
- if (!GGMsockt(gp)) return FALSE; /* Send socket command to server */
-
- GGMclrtx(gp,ip); /* Clear text */
-
- gp->receiving_text = TRUE;
-
- got_some = FALSE;
- do {
- if (GGMgsrvl(gp,&lp,is_cr_needed)) { /* Get server line */
- if (lp) {
- got_some = TRUE;
- (void)GGMouttx(gp,lp,ip); /* Output text line */
- }
- }
- } while (lp); /* until no more lines */
-
- if (!got_some) {
- WARN2("No data available from server %s.\n",gp->ggserver);
- return FALSE;
- }
-
- return TRUE;
-
- }
-
- /****** Gopher it. ***************************************************/
-
- Bool
- GGMgofor(gp,ip,as_file)
- Rstruc ggcb *gp;
- Rstruc gopherinfo *ip;
- Fool as_file;
- {
- Bool con;
- Bool cr;
- Bool (*fun)(struct ggcb *,struct gopherinfo *,Fool);
-
- /* (1) send initial path string to initial host
- * (2) get back data from host
- * (3) if it is a gopher directory, then do:
- * - display "table" of items
- * - for each item selected, call GGMgofor recursively
- * else browse the file data
- * (4) bye
- */
-
- if (gp->debug_mode) {
- fprintf(gp->debug_file,"GGMgofor: type = %d\n",ip->type);
- fprintf(gp->debug_file,"GGMgofor: port = %d\n",ip->port);
- fprintf(gp->debug_file,"GGMgofor: path = %s\n",ip->path);
- fprintf(gp->debug_file,"GGMgofor: host = %s\n",ip->host);
- fprintf(gp->debug_file,"GGMgofor: desc = %s\n",ip->desc);
- }
-
- switch (ip->type) {
- case GOPHER_FILE: fun = GGMvtx; con = TRUE; cr = TRUE; break;
- case GOPHER_DIRECTORY:fun = GGMdir; con = TRUE; cr = TRUE; break;
- case GOPHER_TELNET: fun = GGMtnet; con = FALSE; cr = TRUE; break;
- case GOPHER_TN3270: fun = GGMtnet; con = FALSE; cr = TRUE; break;
- case GOPHER_WAIS: fun = GGMwais; con = FALSE; cr = TRUE; break;
- case GOPHER_WHOIS: fun = GGMwhois; con = FALSE; cr = TRUE; break;
- case GOPHER_CSO: fun = GGMcso; con = FALSE; cr = FALSE;break;
- default:
- ERR2("Sorry, access via %s not supported", GGMtype(ip->type));
- return FALSE;
- }
-
- if (con) {
- if (!connect_to_gopher_server(gp,ip,cr)) return FALSE;
- }
-
- /* Insure no connection is active once we do the real thing. */
-
- if (gp->connected_to_server) {
- (void)GGMdisc(gp); /* Disconnect from gopher server */
- }
-
- return (fun)(gp,ip,as_file);
- }
-
- ./ ADD NAME=GGMGSRVL,SSI=01110001
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@GSRVL")
- #pragma csect(static,"GG$GSRVL")
- #include "gg.h"
-
- /****** Input one character from the server. *************************/
-
- static int
- socket_getchar(gp)
- Rstruc ggcb *gp;
- {
- int readrc;
-
- if (gp->g_buf_index == -1 ||
- gp->g_buf_index >= gp->g_bytes_returned - 1) {
- gp->g_buf_index = -1;
- if (gp->dont_read) return(SOCKET_NO_MORE);
- else {
- TCP_DEBUG_ON;
- readrc = read(gp->socknum, gp->g_buf, READ_BYTES);
- TCP_DEBUG_OFF;
- if (readrc == -1) {
- gp->connection_broken = TRUE;
- return SOCKET_GETCHAR_ERROR;
- }
- else if (readrc == 0) {
- gp->connection_broken = FALSE;
- return SOCKET_READ_NOTHING;
- }
- else {
- #ifdef MVS
- ASCII_TO_EBCDIC(gp->g_buf,readrc);
- #endif
- gp->g_bytes_returned = readrc;
- }
- }
- }
- return gp->g_buf[++gp->g_buf_index];
- }
-
- /****** Input one data line at a time from the server. ***************/
-
- static enum socket_retval
- socket_from_server(gp)
- Rstruc ggcb *gp;
- {
- char *s_buf;
- int s_bytes;
- int s_buf_index;
- int character;
- int previous_character;
-
- s_buf = gp->server_buf;
- s_bytes = SERVER_BUF_MSGSIZE;
-
- /* Get characters from the server until CRLF is reached. */
-
- s_buf_index = 0;
- previous_character = -1;
- for (;;) {
- character = socket_getchar(gp);
- /*
- if (character == LINE_FEED && previous_character == CARRIAGE_RETURN)
- break;
- */
- if (character == LINE_FEED) break;
- if (character == SOCKET_GETCHAR_ERROR) return(SERVER_READ_ERROR);
- if (character == SOCKET_NO_MORE) return(SERVER_NO_MORE);
- if (character == SOCKET_READ_NOTHING) return(SERVER_READ_NOTHING);
- previous_character = character;
- if (s_buf_index >= s_bytes) {
- fprintf(stderr,"Error: gp->server_buf overflowed.\n");
- fprintf(stderr,
- "More than %d bytes collected without CR/LF seen.\n",
- s_bytes);
- if (gp->debug_file) {
- GGMdump(gp,"Data collected so far",gp->server_buf,s_bytes);
- }
- return(SERVER_BUFFER_ERROR);
- }
- if (character == '\0') {
- fprintf(stderr,
- "Warning: null character found in data from server, changed to blank\n"
- );
- character = ' ';
- }
- s_buf[s_buf_index++] = (unsigned char)character;
- }
- s_buf[s_buf_index] = '\0';
- return(SERVER_READ_OK);
- }
-
- /****** Get server line. *********************************************/
-
- Bool
- GGMgsrvl(gp,pointer,is_cr_needed)
- Rstruc ggcb *gp;
- char **pointer;
- Fool is_cr_needed;
- {
- char *sbufp;
- char *p;
- int scan_count;
- Bool something_to_print;
- struct recvstruct *R;
-
- *pointer = NULL;
-
- /* If local mode, read from temporary file until EOF. */
-
- if ((R=gp->recvp)) {
- if (!R->outfp) {
- CRIT1("Can't read data locally, non-socket not connected\n");
- return FALSE;
- }
- fgets(gp->server_buf, SERVER_BUF_MSGSIZE, R->outfp);
- if (ferror(R->outfp)) {
- CRIT1("Error reading local non-socket data\n");
- gp->time_to_go_home = TRUE;
- return FALSE;
- }
- if (feof(R->outfp)) return FALSE;
- if ((p=strchr(gp->server_buf,'\n'))) *p = '\0';
- *pointer = gp->server_buf;
- return TRUE;
- }
-
- if (!gp->receiving_text) return TRUE;
-
- if (gp->server_finished_replying) gp->dont_read = TRUE;
-
- switch (socket_from_server(gp)) {
- case SERVER_READ_OK: break;
- case SERVER_READ_NOTHING: gp->time_to_go_home = TRUE;
- break;
- case SERVER_READ_ERROR: ERR2(
- "Lost server connection. Failure reading data from server %s.",
- gp->ggserver);
- gp->time_to_go_home = TRUE;
- break;
- case SERVER_BUFFER_ERROR: ERR2(
- "Read error. No linefeed character found in data from server %s.",
- gp->ggserver);
- gp->time_to_go_home = TRUE;
- break;
- case SERVER_NO_MORE: gp->server_has_something_pending = FALSE;
- break;
- }
-
- if (gp->time_to_go_home == TRUE) return FALSE;
- if (gp->dont_read == TRUE &&
- gp->server_has_something_pending == FALSE) return TRUE;
-
- something_to_print = TRUE;
-
- sbufp = gp->server_buf;
-
- if (gp->sending_text) {
- if (*sbufp == '.') {
- switch (*(sbufp+1)) {
- case CARRIAGE_RETURN:
- case LINE_FEED:
- case '\0':
- gp->server_finished_replying = TRUE;
- something_to_print = FALSE;
- break;
- case '.':
- break;
- default:
- GGMdump(gp,"Warning, bad period in line from server",
- sbufp,strlen(sbufp));
- break;
- }
- }
- }
-
- gp->sending_text = TRUE;
-
- if (something_to_print) {
- /* Last character of output buffer is a CR without LF. */
- p = sbufp + strlen(sbufp)-1;
- if (p >= sbufp) {
- if (*p == CARRIAGE_RETURN) *p = '\0';
- else if (is_cr_needed) {
- /* Last character of output buffer had better be a LF. */
- if (gp->debug_file) {
- fprintf(gp->debug_file,
- "Warning: No carriage return in data from server (%d bytes):\n%s\n",
- strlen(sbufp), sbufp);
- }
- CRIT2(
- "Carriage return expected but not seen in data from server %s.",
- gp->ggserver);
- }
- *(p+1) = '\0';
- }
- *pointer = sbufp;
- }
-
- if (gp->time_to_go_home) return FALSE;
- else return TRUE;
- }
-
- ./ ADD NAME=GGMIERR,SSI=01000000
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@IERR ")
- #pragma csect(static,"GG$IERR ")
- #include "gg.h"
-
- /****** ISPF error handler. ******************************************/
-
- void
- GGMierr(gp)
- Rstruc ggcb *gp;
- {
- char errbuf[] = "DISPLAY PANEL(ISPTERM)";
- int errlen;
-
- errlen = strlen(errbuf);
- switch (ISPEXEC(&errlen,errbuf)) {
- case 0:
- case 4:
- case 8:
- return;
- default:
- fprintf(stderr,
- "\n*** Severe ISPF error, cannot even display ISPTERM error panel.\n");
- fprintf(stderr,
- "\n*** Return code from ISPF service is %d\n",gp->ispfrc);
- return;
- }
- }
-
- ./ ADD NAME=GGMIGET,SSI=01000045
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@IGET ")
- #pragma csect(static,"GG$IGET ")
- #include "gg.h"
-
- /****** Retrieve the value of an ISPF variable into an integer. ******/
-
- int
- GGMiget(gp,varname)
- Rstruc ggcb *gp;
- char *varname;
- {
- char varbuf[16];
- int vcopy_length;
-
- if (!strchr(varname,' ')) {
- fprintf(stderr,"GGMiget: no blank passed in var name\n");
- return FALSE;
- }
-
- vcopy_length = sizeof(varbuf);
-
- gp->ispfrc = ISPLINK("VCOPY",varname,&vcopy_length,varbuf,"MOVE");
- switch (gp->ispfrc) {
- case 0:
- varbuf[vcopy_length] = '\0';
- return atoi(varbuf);
- case 8:
- return 0;
- case 16:
- fprintf(stderr,
- "Error: ISPF variable buffer too short to get %s\n",
- varname);
- return 0;
- default:
- GGMierr(gp); /* handle ISPF error */
- return 0;
- }
- }
-
- ./ ADD NAME=GGMISPF,SSI=01010021
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@ISPF ")
- #pragma csect(static,"GG$ISPF ")
- #include "gg.h"
-
- /****** Call ISPF service. *******************************************/
-
- Bool
- GGMispf(gp,ispfbuf)
- Rstruc ggcb *gp;
- char *ispfbuf;
- {
- int ispflen;
-
- ispflen = strlen(ispfbuf);
- gp->ispfrc = ISPEXEC(&ispflen,ispfbuf);
- if (gp->ispfrc > 8) {
-
- /* Ignore ADDPOP and REMPOP errors, especially if they are due to
- ISPF V3 not being active. */
-
- if (gp->ispfrc == 20
- && gp->debug_mode == FALSE
- && ispflen >= 6
- && (memcmp(ispfbuf,"ADDPOP",6) == 0
- || memcmp(ispfbuf,"REMPOP",6) == 0)) {
- return TRUE;
- }
-
- GGMierr(gp); /* handle ISPF error */
- return FALSE;
- }
- return TRUE;
- }
-
- ./ ADD NAME=GGMIVGET,SSI=01000024
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@IVGET")
- #pragma csect(static,"GG$IVGET")
- #include "gg.h"
-
- /****** Retrieve the value of an ISPF variable. **********************/
-
- Bool
- GGMivget(gp,varname,varbuf,varbuflen)
- Rstruc ggcb *gp;
- char *varname;
- char *varbuf;
- int varbuflen;
- {
- int vcopy_length;
-
- if (!strchr(varname,' ')) {
- fprintf(stderr,"GGMivget: no blank passed in var name\n");
- return FALSE;
- }
-
- /*
- * If varbuflen is negative, that means that the value is not to be
- * treated as a C string, and the null character is not to be
- * appended to the resulting value. This is used for hex values
- * (like addresses) that are stored in ISPF table row variables.
- */
-
- if (varbuflen < 0) vcopy_length = -varbuflen;
- else vcopy_length = varbuflen;
-
- /* Note that on entry, vcopy_length is an integer that contains
- the length of the buffer. On return it is updated to the length
- of the value returned. Since we have to stick a null character
- on the end of it for C, the actual buffer passed must be at least
- one character longer than the length as defined to ISPF.
- */
-
- gp->ispfrc = ISPLINK("VCOPY",varname,&vcopy_length,varbuf,"MOVE");
- switch (gp->ispfrc) {
- case 0:
- if (varbuflen >= 0)
- varbuf[vcopy_length] = '\0';
- return TRUE;
- case 8:
- strcpy(varbuf,"");
- return TRUE;
- case 16:
- fprintf(stderr,
- "Error: ISPF variable buffer too short to get %s\n",
- varname);
- return FALSE;
- default:
- GGMierr(gp); /* handle ISPF error */
- return FALSE;
- }
- }
-
- ./ ADD NAME=GGMIVPUT,SSI=01000024
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@IVPUT")
- #pragma csect(static,"GG$IVPUT")
- #include "gg.h"
-
- /****** Set the value of an ISPF variable. ***************************/
-
- Bool
- GGMivput(gp,varname,varbuf,varlen)
- Rstruc ggcb *gp;
- char *varname;
- char *varbuf;
- int varlen;
- {
- int vreplace_length;
-
- vreplace_length = (varlen<0 ? strlen(varbuf) : varlen);
-
- gp->ispfrc = ISPLINK("VREPLACE",varname,&vreplace_length,varbuf);
- switch (gp->ispfrc) {
- case 0:
- return TRUE;
- case 16:
- fprintf(stderr,
- "Error: ISPF variable buffer too short to put %s\n",
- varname);
- return FALSE;
- default:
- GGMierr(gp); /* handle ISPF error */
- return FALSE;
- }
- }
-
- ./ ADD NAME=GGMMTFER,SSI=01030000
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@MTFER")
- #pragma csect(static,"GG$MTFER")
- #include "gg.h"
-
- /*********************************************************************/
-
- void
- GGMmtfer(
- int retcode,
- char *kind)
- {
- char *ermsg;
-
- switch (retcode) {
- case MTF_OK:
- ermsg = NULL;
- break;
- case EINACTIVE:
- ermsg = "MTF is inactive";
- break;
- case ESUBCALL:
- ermsg = "The MTF call was issued from a subtask";
- break;
- case EWRONGOS:
- ermsg = "MTF is not supported under CMS, IMS, CICS, or DB2";
- break;
- case EACTIVE:
- ermsg = "MTF has already been initialized and is active";
- break;
- case ENAME2LNG:
- ermsg = "The parallel module name is longer than 8 characters";
- break;
- case ETASKNUM:
- ermsg = "The number of tasks specified is invalid";
- break;
- case ENOMEM:
- ermsg = "Insufficient storage for MTF internal areas";
- break;
- case EMODFIND:
- ermsg = "The parallel load module was not found";
- break;
- case EMODREAD:
- ermsg = "The parallel load module was not sucessfully read";
- break;
- case EMODFMT:
- ermsg = "The parallel load module format is invalid";
- break;
- case EAUTOALC:
- ermsg = "Automatic allocation of standard stream DD failed";
- break;
- case ETASKFAIL:
- ermsg = "The attempt to attach task(s) has failed";
- break;
- case ETASKABND:
- ermsg = "One or more subtasks have abnormally terminated";
- break;
- case EBADLNKG:
- ermsg = "TSCHED has been invoked via invalid linkage";
- break;
- case ETASKID:
- ermsg = "The task ID specified is not valid";
- break;
- case EENTRY:
- ermsg = "The parallel function was not in the parallel module";
- break;
- default:
- ermsg = "Unknown MTF error";
- break;
- }
-
- if (ermsg) {
- fprintf(stderr,"GGSERVER: %s error code %d:\n %s\n",
- kind, retcode, ermsg);
- }
-
- return;
-
- }
-
- ./ ADD NAME=GGMOUTS,SSI=01050059
-
- /********************************************************************/
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@MOUTS")
- #pragma csect(static,"GG$MOUTS")
-
- #include "gg.h"
- /*
- ***********************************************************************
- * *
- * This is a Gopher server routine that outputs data to a socket. *
- * *
- * If the "socket" is actually a file pointer, then output is *
- * written to the file pointer. *
- * *
- ***********************************************************************
- */
-
- /*=================================================================*/
-
- Bool
- GGMouts(struct recvstruct *R,
- char *text)
- {
- int len;
- int reallen;
- Bool rc;
- char outbuf[515]; /* hold an output character string */
-
- if (R->outfp) { /* if using non-socket interface */
- if (fputs(text,R->outfp) < 0) {
- fprintf(stderr,"Error writing to output file\n");
- return FALSE;
- }
- if (fputc('\n',R->outfp) < 0) {
- fprintf(stderr,"Error writing to output file\n");
- return FALSE;
- }
- return TRUE;
- }
-
- if (text == NULL) {
- outbuf[0] = '.';
- len = 1;
- }
- else {
- len = strlen(text);
- if (len >= sizeof(outbuf)-3) len = sizeof(outbuf)-3;
- if (text[0] == '.') {
- outbuf[0] = '.';
- memcpy(outbuf+1,text,len);
- len++;
- }
- else {
- memcpy(outbuf,text,len);
- }
- }
- outbuf[len ] = CARRIAGE_RETURN;
- outbuf[len+1] = LINE_FEED;
- outbuf[len+2] = '\0';
- reallen = len + 2;
-
- #ifdef SNSTCPIP
- EBCDIC_TO_ASCII(outbuf,reallen);
- #else
- ebdtoasc(outbuf);
- #endif
-
- rc = TRUE;
-
- if (R->outlen + reallen > sizeof(R->sockbuf)) {
-
- if (write(R->sockfd,R->sockbuf,R->outlen) < 0) {
- REPORT_TCP_ERROR("SEND");
- rc = FALSE;
- }
- R->outlen = 0;
- }
-
- memcpy(R->sockbuf + R->outlen, outbuf, reallen);
- R->outlen += reallen;
-
- if (text == NULL) { /* flush socket */
- if (write(R->sockfd,R->sockbuf,R->outlen) < 0) {
- REPORT_TCP_ERROR("SEND");
- rc = FALSE;
- }
- }
- return rc;
- }
-
- ./ ADD NAME=GGMOUTTX,SSI=01010057
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@OUTTX")
- #pragma csect(static,"GG$OUTTX")
- #include "gg.h"
-
- /****** Output a line of text retrieved from the server. *************/
-
- struct textline *
- GGMouttx(gp,line,ip)
- Rstruc ggcb *gp;
- char *line;
- Rstruc gopherinfo *ip;
-
- {
- struct texthdr *thp;
- struct textline *tp;
- short line_length;
- short total_text_length;
- short tab_expansion_length;
- Bool tabs_present;
- char *p;
- char *q;
- char *t;
- int e;
- int u;
-
- static char tab_expansion_buffer[8*TEXT_BYTES];
-
- thp = (ip ? &ip->thdr : &gp->thdr);
-
- /* If line starts with double period, make it a single period. */
-
- if (ip && memcmp(line,"..",2) == 0) line++;
-
- /* Add this line to the current queue of server text lines. */
-
- /* First, expand tabs in the line. */
-
- line_length = strlen(line);
- t = strchr(line,'\t');
- if (t == NULL) {
- tabs_present = FALSE;
- total_text_length = line_length + 1;
- }
- else { /* expand tabs */
- tabs_present = TRUE;
- p = line;
- q = line + line_length;
- e = 0;
- memset(tab_expansion_buffer,' ',sizeof(tab_expansion_buffer));
- while (TRUE) {
- u = t-p;
- if (u > 0) {
- memcpy(tab_expansion_buffer+e,p,u);
- e += u;
- }
- if (t == q) break;
- e = e / 8 * 8 + 8;
- p = t+1;
- t = strchr(p,'\t');
- if (t == NULL) t = q;
- }
- tab_expansion_length = e;
- tab_expansion_buffer[tab_expansion_length] = '\0';
- total_text_length = line_length + tab_expansion_length + 1;
- }
-
- GETMAIN(tp, char, offsetof(struct textline, text) + total_text_length,
- "text line");
-
- if (tp == NULL) {
- ERR1("There is not enough virtual storage to process server text.");
- return NULL;
- }
-
- tp->next = NULL;
- tp->text_length = line_length;
- strcpy(tp->text,line);
- if (tabs_present) {
- tp->tab_expanded_text_length = tab_expansion_length;
- tp->tab_expanded_text = tp->text + line_length;
- strcpy(tp->tab_expanded_text,tab_expansion_buffer);
- }
- else {
- tp->tab_expanded_text_length = line_length;
- tp->tab_expanded_text = tp->text;
- }
-
- if (thp->last_text_line == NULL) {
- thp->first_text_line = tp;
- thp->text_body_line = tp;
- thp->current_text_line = tp;
- }
- else thp->last_text_line->next = tp;
-
- thp->last_text_line = tp;
- thp->text_line_count++;
-
- if (thp->text_max_length < tp->text_length)
- thp->text_max_length = tp->text_length;
- if (thp->text_max_tab_expanded_length < tp->tab_expanded_text_length)
- thp->text_max_tab_expanded_length = tp->tab_expanded_text_length;
-
- return tp;
-
- }
-
- ./ ADD NAME=GGMPMSG,SSI=01000057
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #define SUPPRESS_V_DECLARATION
- #pragma csect(code, "GG@PMSG ")
- #pragma csect(static,"GG$PMSG ")
- #include "gg.h"
-
- /****** Set an ISPF message, or write to SYSOUT if batch mode. *******/
-
- void
- GGMpmsg(gp,msgtype,msghelp,msgformat) /* also ... for sprintf args */
- Rstruc ggcb *gp;
- int msgtype;
- char *msghelp;
- char *msgformat;
- {
- va_list argp;
- char *cp;
- char zerrsm [25];
- char zerrhm [9];
- char zerralrm [4];
- char zerrlm [73];
- char buf [257];
-
- va_start(argp,msgformat);
- vsprintf(buf,msgformat,argp);
- va_end(argp);
-
- cp = strchr(buf,';');
- if (cp) {
- *cp = '\0';
- strncpy(zerrsm,buf, sizeof(zerrsm));
- strncpy(zerrlm,cp+1,sizeof(zerrlm));
- }
- else {
- strcpy(zerrsm,"");
- strncpy(zerrlm,buf,sizeof(zerrlm));
- }
-
- zerrsm[sizeof(zerrsm)-1] = '\0';
- zerrlm[sizeof(zerrlm)-1] = '\0';
-
- if (msghelp) strcpy(zerrhm, msghelp);
- else strcpy(zerrhm, "*" );
-
- switch (msgtype) {
- case NOTIFY_MSG: strcpy(zerralrm,"NO "); break;
- case WARNING_MSG:
- case CRITICAL_MSG:
- default: strcpy(zerralrm,"YES"); break;
- }
-
- (void)GGMivput(gp,"ZERRSM ", zerrsm, -1);
- (void)GGMivput(gp,"ZERRLM ", zerrlm, -1);
- (void)GGMivput(gp,"ZERRHM ", zerrhm, -1);
- (void)GGMivput(gp,"ZERRALRM ",zerralrm, -1);
-
- if (gp->brifp) {
- (void)GGMispf(gp,"SETMSG MSG(ISRZ002)");
- }
- else {
- gp->setmsg = TRUE;
- }
-
- return;
- }
-
- ./ ADD NAME=GGMPROC,SSI=01160000
-
- /********************************************************************/
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@MPROC")
- #pragma csect(static,"GG$MPROC")
-
- #pragma linkage(IRXEXEC,OS)
-
- #include "gg.h"
-
- /**********************************************************************
- * *
- * Changes: 02/17/93 Fixed memcmp logic in append-domain-name code. *
- * *
- **********************************************************************/
-
- /*=================================================================*/
-
- /*******************************************************************/
- /* This routine cleans up a token. It converts all chars to */
- /* upper case and removes any leading spaces. Note that the */
- /* string is assumed to be null terminated. */
- /* */
- /* INPUT token pointer to token string. */
- /* OUTPUT *token string upcased, blanks removed. */
- /*******************************************************************/
-
- static char *
- uppercase_and_trim_leading_space(char *token)
- {
-
- uppercase_in_place(token);
-
- return token + strspn(token," ");
- };
-
- /*=================================================================*/
-
- /****************************************************/
- /* This routine "cleans" a string by removing the */
- /* leading spaces and trailing spaces+non-printable */
- /* characters. */
- /****************************************************/
-
- static char *
- trim_leading_and_trailing_space(char *string)
- {
- char *str;
- char *ptr;
-
- /* first clean up the beginning of the string... */
-
- str = string + strspn(string," \t");
-
- /* now look at the end of the string... */
-
- ptr = str+strlen(str)-1;
- while (!isgraph(*ptr) && ptr >=str) ptr--;
- *(ptr+1)=0;
-
- return str;
- }
-
- /*=================================================================*/
-
- /****************************************************/
- /* This routine "cleans" an output line by removing */
- /* trailing spaces and non-printable characters. */
- /****************************************************/
-
- static void
- trim_trailing_space(char *string)
- {
- char *ptr;
-
- ptr = string;
-
- /* look at the end of the string... */
-
- ptr = string+strlen(string)-1;
- while (isgraph(*ptr)==0 && ptr >=string) ptr--;
- *(ptr+1)=0;
- }
-
- /*=================================================================*/
-
- static void
- gbarf(struct recvstruct *R,
- char *message)
- {
- char temp[257];
-
- /* the number should be 3 (ERROR) but some clients may not show it
- * |
- * |
- * |
- * V
- */
- sprintf(temp, "1Sorry, %s.\t0\t0\t0", message);
-
- (void)GGMouts(R,temp);
-
- return;
- }
-
- /*=================================================================*/
-
- static Bool
- insure_my_name(struct recvstruct *R)
- {
- int hostlen;
- int domslen;
-
- /* Determine the local path name, if not already set. */
-
- if (!*R->myname) {
- if (gethostname(R->myname,MAXHOSTNAMELEN) < 0) {
- fprintf(stderr,"GOPHER:gethostname() failed, can't get my name\n");
- gbarf(R,"the GOPHER server had an attack of amnesia");
- return FALSE;
- }
-
- #ifdef APPEND_DOMAIN_NAME_TO_SELF
-
- hostlen = strlen(R->myname);
- domslen = sizeof(MY_DOMAIN_SUFFIX) - 1;
- if (hostlen <= domslen ||
- memcmp(R->myname+hostlen-domslen, MY_DOMAIN_SUFFIX, domslen)) {
- strncat(R->myname,MY_DOMAIN_SUFFIX,domslen);
- }
-
- #endif
-
- uppercase_in_place(R->myname);
-
- fprintf(stderr,"Local hostname set to '%s'\n",R->myname);
-
- }
-
- return TRUE;
-
- }
-
- /*=================================================================*/
-
- static Bool
- authorized_file(struct recvstruct *R)
- {
- char *cp;
- FILE *afp;
- int n;
- int hostcount;
- Bool rc;
- char filetest[RBUFSIZE];
- char accline [RBUFSIZE];
- char accfile [RBUFSIZE];
- char acchost [RBUFSIZE];
-
- /* If non-socket interface, bypass the authorization check. */
-
- if (R->outfp) return TRUE;
-
- /* Check that the server is allowed to return data from the file
- * specified in R->fileptr. Note that this could be the name of
- * an exec. The name will be (dataset), EXEC:execname, or DD:file
- * - we look at only the first part, whitespace-delimited.
- * Entries in the file authorization table look as above.
- */
-
- rc = FALSE;
- filetest[0] = '\0';
- sscanf(R->fileptr,"%s",filetest);
-
- /* Read authorization file. */
-
- afp = fopen(ACCESS_TABLE,"r");
- if (!afp) {
- perror(ACCESS_TABLE);
- fflush(stderr);
- return FALSE;
- }
-
- for (;;) {
- fgets(accline, sizeof(accline), afp);
- if (ferror(afp)) {
- fprintf(stderr,"Error reading access table %s\n",ACCESS_TABLE);
- fflush(stderr);
- break;
- }
- if (feof(afp)) break;
- /* format of line is: filename machine(s) */
- uppercase_in_place(accline);
- cp = accline; /* Start scan pointer */
- *accfile = '\0'; /* Clear access file name */
- sscanf(cp,"%s %n",accfile,&n); /* Get file name, bump scan */
- if (!strcmp(filetest,accfile)) { /* If file name matches */
- hostcount = 0; /* Clear access host count */
- for (;;) { /* Loop over access host ids */
- cp += n; /* Bump to next word in file */
- *acchost = '\0'; /* Clear word before scanf */
- sscanf(cp,"%s %n",acchost,&n); /* Get next word, bump scan */
- if (!*acchost) break; /* exit loop if no more hosts */
- hostcount++; /* increment access host count*/
- if (!strcmp(R->hostname,acchost)
- || !strcmp(R->hosttest,acchost)) { /* if hostname matches */
- rc = TRUE; /* access is allowed */
- break;
- }
- }
- if (!rc) { /* If no matching host found */
- if (hostcount == 0) rc = TRUE; /* if no access hosts, say OK */
- }
- if (rc) break; /* if access OK, finished */
-
- /* If access is not permitted, we keep checking because
- * there may be more than one entry in the access table
- * for this file, so that many host names can be given.
- */
-
- }
- }
-
- (void)fclose(afp);
-
- if (!rc) {
- fprintf(stderr,"Not authorized from %s: '%s'\n",
- R->hosttest, filetest);
- }
-
- fflush(stderr);
-
- return rc;
- }
-
- /*=================================================================*/
-
- /*******************************************************************/
- /* This routine determines what type of gopher file */
- /* we've opened. We'll return the file type to the */
- /* caller. */
- /* */
- /* INPUT: ident pointer to first line of file */
- /* */
- /* OUTPUT: MENU file type is a menu */
- /* FILE file type is a file */
- /* INDEX file type is an INDEX (not done) */
- /*******************************************************************/
-
- static char
- getftype(char *ident)
- {
- int x; /* loop counter */
- char buffer[RBUFSIZE];
- char *bufptr;
-
- /**********/
- /* first, convert the string to upper case... */
- /*********/
- strcpy(buffer,ident);
- bufptr = uppercase_and_trim_leading_space(buffer);
-
- /**********/
- /* return the type of file. */
- /*********/
-
- if(strcmp(bufptr,MENUIDENT)==0) return(MENU);
- if(strcmp(bufptr,INDEXIDENT)==0) return(INDEX);
-
- /**********/
- /* don't know, so assume it's a "file" file... */
- /*********/
-
- return(GFILE);
-
- }
-
- /*=================================================================*/
-
- /*******************************************************************/
- /* This routine figures out what type of parm line */
- /* the current line is. We'll return the token */
- /* type to the caller. */
- /* */
- /* INPUT: buffer pointer to first line of file */
- /* (Note: string must be null terminated! */
- /* OUTPUT: Type of token. (See in include file...) */
- /*******************************************************************/
-
- static int
- menukeywd(char *buffer,
- char *token,
- char *operand)
- {
- int x; /* loop counter */
- char *tokval;
- char *oprval;
- char *tokptr;
- char tokstr[256];
-
- strcpy(tokstr,buffer);
- tokval=strtok(tokstr,"=");
- oprval=strtok(NULL,"");
- strcpy(token,tokval);
- strcpy(operand,oprval);
- tokptr = uppercase_and_trim_leading_space(token);
-
- /*********/
- /* now look at the tokens to see if we have a weener... */
- /*********/
-
- if(strcmp(tokptr,TOKTYPE)==0) return(TYPETOK);
- if(strcmp(tokptr,TOKNAME)==0) return(NAMETOK);
- if(strcmp(tokptr,TOKPATH)==0) return(PATHTOK);
- if(strcmp(tokptr,TOKHOST)==0) return(HOSTTOK);
- if(strcmp(tokptr,TOKPORT)==0) return(PORTTOK);
- if(strcmp(tokptr,TOKEND)==0) return(ENDTOK);
-
- /* for back compatibility with the old MVS GOPHER server */
-
- if(strcmp(tokptr,TOKDISPLAY)==0) return(DISPLAYTOK);
- if(strcmp(tokptr,TOKSELECT)==0) return(SELECTTOK);
-
- return(COMMENTTOK);
-
- }
-
- /*=================================================================*/
-
- /*******************************************************************/
- /* This routine reads a line from the specified file. */
- /* if a read error occurs, an error message is printed and */
- /* FALSE is returned. */
- /* */
- /* INPUT buffer pointer to buffer to place line */
- /* readfile file structure to read from */
- /* */
- /* OUTPUT buffer line that was read from the file */
- /* TRUE read worked ok */
- /* FALSE read failed! */
- /*******************************************************************/
-
- static Bool
- readaline(struct recvstruct *R)
- {
-
- memset(R->buffer,0,RBUFSIZE);
- fread(R->buffer,RBUFSIZE,1,R->readfile);
- if (ferror(R->readfile)) {
- /* perror("FREAD"); */
- fprintf(stderr,"GGSTASK: Error reading file\n");
- return(FALSE);
- }
- trim_trailing_space(R->buffer); /* Remove trailing whitespace */
- return(TRUE);
- }
-
- /*=================================================================*/
-
- /*******************************************************************/
- /* This routine sends a file to the calling client. */
- /* It assumes the file is a text formatted file. */
- /* INPUT: buffer pointer to the already read line... */
- /* readfile file we're going to read from.. */
- /* maxlen size of the buffer. */
- /* sockfd socket descriptor for client. */
- /* */
- /* OUTPUT: send the file to the client */
- /*******************************************************************/
- static void
- sendafile(struct recvstruct *R)
- {
- int x;
- char *moveit;
-
- /*******/
- /* send the first line (cause we already read it) */
- /*******/
-
- if (!GGMouts(R,R->buffer)) return;
-
- /*******/
- /* get the rest of the lines of the file and send them... */
- /*******/
-
- for (;;) {
- if (!readaline(R)) {
- (void)GGMouts(R,"<<<*** I/O ERROR ON MVS FILE ***>>>");
- return;
- }
- if (feof(R->readfile)) break;
- if (!GGMouts(R,R->buffer)) return;
- }
- }
-
- /*=================================================================*/
-
- /*******************************************************************/
- /* This routine formats a menu file into gopher data & sends it */
- /* to the client. */
- /* INPUT: buffer pointer to the already read line... */
- /* readfile file we're going to read from.. */
- /* maxlen size of the buffer. */
- /* sockfd socket descriptor for client */
- /* */
- /* OUTPUT: send the menu to the client */
- /*******************************************************************/
-
- #define MENU_STUFF_SIZE GOPHER_DESC_LENGTH + \
- GOPHER_PATH_LENGTH + \
- GOPHER_HOST_LENGTH + 20
-
- static void
- sendamenu(struct recvstruct *R)
- {
- char *moveit;
- char *operptr;
- char *typeoftype; /*pointer for strtok */
- char *cp;
- int kindotoken;
- int x; /* loop counter */
- char token [133];
- char operand [133];
- char outbuf [MENU_STUFF_SIZE];
- struct menuitem menu;
-
- memset(&menu,0,sizeof menu );
- for (;;) {
- if (!readaline(R)) break;
- if (feof(R->readfile)) break;
- if (!*R->buffer) continue;
- kindotoken = menukeywd(R->buffer,token,operand);
- switch(kindotoken) {
- case TYPETOK:
- operptr = uppercase_and_trim_leading_space(operand);
- typeoftype = strtok(operptr," ");
- if (strlen(typeoftype) == 1) menu.type = *typeoftype;
- else
- if (EQUAL(typeoftype,TYPEFILE)) menu.type = GFILE;
- else
- if (EQUAL(typeoftype,TYPEMENU)) menu.type = MENU;
- else
- if (EQUAL(typeoftype,TYPEINDEX)) menu.type = INDEX;
- else
- if (EQUAL(typeoftype,TYPETELNET)) menu.type = TELNET;
- else
- if (EQUAL(typeoftype,TYPETN3270)) menu.type = TN3270;
- else
- if (EQUAL(typeoftype,TYPEWHOIS)) menu.type = WHOIS;
- else menu.type = ERROR;
- break;
- case NAMETOK:
- case DISPLAYTOK:
- strncpy(menu.desc, operptr, sizeof(menu.desc));
- break;
- case PATHTOK:
- case SELECTTOK:
- strncpy(menu.select, operptr, sizeof(menu.select));
- break;
- case HOSTTOK:
- if (EQUAL(operptr,IDENT_HOST_FROB)) { /* HOST=+ */
- if (insure_my_name(R)) {
- strncpy(menu.hostname, R->myname, sizeof(menu.hostname));
- }
- }
- else {
- strncpy(menu.hostname, operptr, sizeof(menu.hostname));
- }
- break;
- case PORTTOK:
- if (EQUAL(operptr,IDENT_HOST_FROB)) { /* PORT=+ */
- menu.port = SERV_TCP_PORT;
- }
- else {
- menu.port=atoi(operptr);
- }
- break;
- case ENDTOK:
- if (menu.port == 0) {
- switch (menu.type) {
- case TELNET: break;
- case TN3270: break;
- default: menu.port = GOPHER_PORT_NUMBER; break;
- }
- }
- /* If host is local and path is in the form "(member)",
- * and current dsname is a PDS, then use same PDS:
- * i.e. turn PATH=(FOOBAR) into PATH=AA.BB.CC(FOOBAR)
- */
- if (*R->myname
- && EQUAL(menu.hostname,R->myname)
- && *menu.select == '(' /* ) */
- && (cp = strchr(R->dsname,'(' /* ) */ ))) {
- memcpy(outbuf, R->dsname, (cp-R->dsname));
- strcpy(outbuf+(cp-R->dsname), menu.select);
- strncpy(menu.select, outbuf, sizeof(menu.select));
- }
- if (*menu.desc && *menu.hostname) {
- sprintf(outbuf,"%c%s\t%s\t%s\t%d",
- menu.type,menu.desc,
- menu.select,menu.hostname,menu.port);
- if (!GGMouts(R,outbuf)) return;
- }
- fflush(stdout);
- memset(&menu,0,sizeof menu );
- break;
- default:
- break;
- }
- }
- }
-
- /*=================================================================*/
-
- static Bool
- get_directory(struct recvstruct *R)
- {
- FILE *dirfile;
- int i;
- short block_count;
- short bump_amount;
- Bool reject;
- Bool no_more;
- char *cp;
- char *mp;
- char dirblk [256];
- char pdsspec [256];
- char entry [256];
-
- /* The local path name is required for this function. */
-
- if (!insure_my_name(R)) return FALSE;
-
- if ((dirfile=fopen(R->buffer,"rb,recfm=u,lrecl=256")) == NULL) {
- perror(R->buffer);
- printf("Can't open PDS directory:%s\n",R->dsname);
- gbarf(R,"the GOPHER server can't open the directory");
- return(FALSE);
- }
-
- while (!feof(dirfile)) {
-
- no_more = FALSE;
-
- do {
- memset(dirblk,0x00,256);
- fread(dirblk,256,1,dirfile);
- if (feof(dirfile)) break;
- if (ferror(dirfile)) {
- printf("Can't read PDS directory:%s\n", R->fileptr);
- gbarf(R,"the GOPHER server can't read the directory");
- fclose(dirfile);
- return FALSE;
- }
- mp = dirblk;
- block_count = *(short *)mp - 2; /* # bytes in dir block */
- mp += 2; /* addr of dir block data */
- while (block_count > 0) {
- if (memcmp(mp,"\xff\xff\xff\xff\xff\xff\xff\xff",8)==0) break;
- reject = FALSE;
- /*
- * Uncomment this if you want to skip aliases.
- * It is recommended that you let aliases through, since
- * they often have better names (e.g. TSO HELP files)
- *
- * if ((mp[11] & 0x80) != 0) {
- * fprintf(stderr,"Skipping alias: %-8.8s\n",mp);
- * reject = TRUE;
- * }
- */
- if (!reject) {
- strcpy(pdsspec, R->dsname);
- cp = strchr(pdsspec, '\0');
- *(cp++) = '(';
- for (i = 0; i < 8 && mp[i] != ' '; cp++, i++) *cp = mp[i];
- *(cp++) = ')';
- *cp = '\0';
- sprintf(entry,"0%8.8s\t%s\t%s\t%d",
- mp, pdsspec, R->myname, SERV_TCP_PORT);
- (void)GGMouts(R,entry);
- }
- bump_amount = 12 + ((mp[11] & 0x1f) * 2);
- mp += bump_amount;
- block_count -= bump_amount;
- }
- } while(!no_more);
-
- }
-
- fclose(dirfile);
- return TRUE;
- }
-
- /*=================================================================*/
-
- static Bool
- get_flat_file(struct recvstruct *R)
- {
- int x; /* loop counter*/
- int numread; /* number of items read... */
- char filetype; /* type of file we're dealing with*/
-
- if ((R->readfile=fopen(R->buffer,"rb,type=record")) == NULL) {
- perror(R->buffer);
- printf("INVALID! requested:%s\n",R->fileptr);
- gbarf(R,"the GOPHER server couldn't open the file");
- return(FALSE);
- }
-
- /************/
- /* get the first line and see what type of file we've got. */
- /************/
-
- if (readaline(R) && !feof(R->readfile)) {
-
- filetype=getftype(R->buffer);
-
- /************/
- /* Now let's go do whatever we need to for this file type. */
- /************/
-
- switch(filetype) {
- case MENU:
- sendamenu(R);
- break;
- case GFILE:
- default:
- sendafile(R);
- break;
- }
-
- }
-
- if(fclose(R->readfile) < 0) {
- /* perror("PROCESS CLOSE"); */
- fprintf(stderr,"GGSTASK: Error closing file %s\n",R->fileptr);
- gbarf(R,"the GOPHER server couldn't close the file");
- return FALSE;
- }
-
- return TRUE;
-
- }
-
- /*=================================================================*/
-
- #define PARAMETER unsigned int
- #define LASTPARM(X) ((unsigned int)(X) | 0x80000000)
-
-
- static Bool
- get_exec_data(struct recvstruct *R)
- {
- char *command;
- char *commandargs;
- unsigned int bitflags;
- int rexxrc;
- int irxexecrc;
- int commandlength;
- int scan_count;
- int i;
- Bool rc;
- int (*irxexec)();
- FILE *fp;
- char exectest[RBUFSIZE];
- PARAMETER parameter[11];
- struct {
- /* repeat this block for each argument */
- char *argstring_ptr;
- int argstring_length;
- /* end repeat this block for each argument */
- int argstring_end;
- } arguments;
-
- struct {
- char acryn[8]; /* "IRXEXECB" */
- int length;
- int reserved1;
- char member[8];
- char ddname[8];
- char subcom[8];
- char *dsnptr;
- int dsnlen;
- } execblk;
-
- /*
- * Menu item should look like this:
- *
- * exec:rexxname any args
- *
- * The exec should write output to SYSTSPRT. Normal TSO command
- * output will be captured by the SYSTSPRT allocation only if
- * the Gopher server is run as a batch job.
- *
- * If this was sent by the client with a type 7 or type w, then
- * additional args will appear at the end delimited by a space.
- */
-
- irxexec = NULL;
- rc = TRUE;
- scan_count = 0;
-
- if (R->wargptr) {
- commandlength = strlen(R->fileptr) + strlen(R->wargptr) + 4;
- command = (char *)malloc(commandlength);
- if (!command) {
- printf("Cannot allocate %d bytes of memory for exec\n",
- commandlength);
- gbarf(R,"the GOPHER server ran out of memory");
- return FALSE;
- }
- else sprintf(command,"%s %s",R->fileptr,R->wargptr);
- }
- else {
- commandlength = 0;
- command = R->fileptr;
- }
-
- *exectest = '\0';
- sscanf(command, "%s %n", exectest, &scan_count);
- if (strlen(exectest) > 8) {
- gbarf(R,"name of exec is too long");
- return FALSE;
- }
- commandargs = command + scan_count;
-
- if (rc) {
- irxexec = (int(*)())fetch("IRXEXEC");
- if (!irxexec) {
- printf("Cannot fetch IRXEXEC\n");
- rc = FALSE;
- }
- }
-
- /* Give the exec an empty SYSTSPRT file to write into.
- * Then when we read it we can see only what was added.
- * Since IRXEXEC doesn't close SYSTSPRT, we can't remove it
- * and reallocate it.
- */
-
- if (rc) {
- fp = fopen("DD:SYSTSPRT","w");
- if (!fp) {
- perror("DD:SYSTSPRT");
- printf("Cannot open SYSTSPRT to prepare for REXX exec\n");
- rc = FALSE;
- }
-
- /* Open for write + close = clear it out */
-
- else if (fclose(fp) < 0) {
- printf("Cannot close SYSTSPRT to prepare for REXX exec\n");
- rc = FALSE;
- }
- }
-
- /* Set up parameters for IRXEXEC:
- *
- * Param 1 - address of EXECBLK
- * Param 2 - address of arguments
- * Param 3 - bitflags
- * Param 4 - address of INSTBLK
- * Param 5 - address of CPPL
- * Param 6 - address of EVALBLOCK
- * Param 7 - address of 8-byte work area
- * Param 8 - address of user field
- * Param 9 - address of environment block
- * Param 10 - return code
- *
- */
-
- if (rc) {
-
- /* set up exec block */
-
- memset (&execblk, 0, sizeof(execblk));
- execblk.length = sizeof(execblk);
- memcpy (execblk.acryn, "IRXEXECB", 8);
- strncpy(execblk.member,exectest,8);
- for (i=0;i<8;i++) {
- if (execblk.member[i] == '\0')
- execblk.member[i] = ' ';
- }
- /* We may have just clobbered this, so do this after... */
-
- memcpy (execblk.ddname, REXX_EXEC_LIBRARY_DDNAME, 8);
- memcpy (execblk.subcom, REXX_EXEC_SUBCOM, 8);
-
- /* set up arguments */
-
- arguments.argstring_ptr = commandargs;
- arguments.argstring_length = strlen(commandargs);
- arguments.argstring_end = 0xffffffff;
-
- /* Invoke the rexx exec */
-
- if (!R->outfp) printf("Executing:%s\n", command);
-
- #define INVOKE_EXEC_AS_COMMAND (unsigned int)0x80000000
- #define INVOKE_EXEC_AS_EXTERNAL_FUNCTION (unsigned int)0x40000000
- #define INVOKE_EXEC_AS_SUBROUTINE (unsigned int)0x20000000
- #define RETURN_EXTENDED_RETURN_CODES (unsigned int)0x10000000
-
- rexxrc = 0;
- bitflags = (unsigned int)(INVOKE_EXEC_AS_COMMAND +
- RETURN_EXTENDED_RETURN_CODES);
-
- parameter[ 1] = (PARAMETER)&execblk;
- parameter[ 2] = (PARAMETER)&arguments;
- parameter[ 3] = (PARAMETER)bitflags;
- parameter[ 4] = (PARAMETER)NULL; /* no INSTBLK */
- parameter[ 5] = (PARAMETER)NULL; /* no CPPL */
- parameter[ 6] = (PARAMETER)NULL; /* no eval block */
- parameter[ 7] = (PARAMETER)NULL; /* no work area */
- parameter[ 8] = (PARAMETER)NULL; /* no user field, last parm */
- parameter[ 9] = (PARAMETER)NULL; /* no environment block */
- parameter[10] = (PARAMETER)0; /* return code */
-
- irxexecrc = (*irxexec) (
- ¶meter[1],
- ¶meter[2],
- ¶meter[3],
- ¶meter[4],
- ¶meter[5],
- ¶meter[6],
- ¶meter[7],
- LASTPARM(¶meter[8]), /* old REXX */
- ¶meter[9],
- LASTPARM(¶meter[10]) /* new REXX */
- );
-
- if (irxexecrc != 0) {
- fprintf(stderr,"Return code from IRXEXEC is %d\n", irxexecrc);
- gbarf(R,"the Gopher server was unable to run the exec");
- rc = FALSE;
- }
- else {
-
- rexxrc = parameter[10];
-
- if (!R->outfp) printf("Return code from exec is %d\n", rexxrc);
-
- /* Read what the exec wrote. */
-
- strcpy(R->buffer,"DD:SYSTSPRT");
- R->fileptr = R->buffer;
- rc = get_flat_file(R);
-
- }
-
- }
-
- else {
- gbarf(R,"the GOPHER server had a problem with the exec");
- }
-
- if (irxexec) release((void (*)())irxexec);
-
- if (commandlength > 0) free(command);
-
- return rc;
-
- }
-
- /*=================================================================*/
-
- /*******************************************************************/
- /* This routine Processes the file the user requested. */
- /* If it's a menu, we'll form a menu line, if it's a */
- /* file, we'll just send it as is. */
- /* */
- /* INPUT: filename pointer to the file name to open */
- /* sockfd socket descriptor for the client */
- /* */
- /* OUTPUT: print "gopher" lines. */
- /* TRUE - file printed ok. */
- /* FALSE - Error reading or writing */
- /*******************************************************************/
-
- Bool
- GGMproc(struct recvstruct *R)
- {
- int x; /* loop counter*/
- int numread; /* number of items read... */
- int hacksize; /* length of hack prefix before : */
- Bool rc; /* return value */
- enum data_set_type dstype; /* SEQ, PDS or UNK */
- char *p;
- char *q;
- char *tabptr;
- char *colonptr;
- char ddname [ 9];
- char hackprefix[ 17];
-
- *ddname = '\0';
- *hackprefix = '\0';
-
- /************/
- /* First, strip off any "bad" characters from the arguments. */
- /************/
-
- /*
- * Break the argument up into one or two pieces delimited by tab.
- */
-
- R->fileptr = R->buffer; /* filename passed in buffer */
-
- tabptr = strchr(R->fileptr,'\t');
- if (tabptr) {
- *tabptr = '\0';
- R->fileptr = trim_leading_and_trailing_space(R->fileptr);
- R->wargptr = trim_leading_and_trailing_space(tabptr+1);
- }
- else {
- R->fileptr = trim_leading_and_trailing_space(R->fileptr);
- R->wargptr = NULL;
- }
-
- if (!*R->fileptr) {
- R->fileptr = DEFAULT_DIRECTORY;
- }
-
- /* If first character is numeric, assume it's a gopher type.
- * Later we will actually support different types...
- */
-
- switch (*R->fileptr) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': R->fileptr++; break;
- default: break;
- }
-
- if (!R->outfp) printf("%s: requested:%s;\n",R->hostname,R->fileptr);
-
- /*
- * Process special hacks here.
- *
- * For example, if the file name begins with "exec:", then
- * execute the specified REXX exec.
- *
- * Hackless names are processed as files. "dd:" is not a
- * special hack but the normal C/370 DDname reference.
- *
- */
-
- colonptr = strchr(R->fileptr,':');
- if (colonptr) {
- hacksize = colonptr - R->fileptr;
- if (hacksize > 0 && hacksize < sizeof(hackprefix)) {
- for (p = hackprefix, q = R->fileptr;
- hacksize > 0;
- p++, q++, hacksize--) *p = toupper(*q);
- *p = '\0';
- }
- }
-
- if (EQUAL(hackprefix,"EXEC")) {
- /*
- * REXX exec, which must reside in SYSEXEC DD.
- */
- if (!authorized_file(R)) {
- gbarf(R,"the GOPHER server won't run the exec for you");
- rc = FALSE;
- }
- else {
- R->fileptr = colonptr + 1; /* point to exec itself */
- rc = get_exec_data(R);
- }
- }
- else
- if (EQUAL(hackprefix,"DD")) {
- /*
- * C/370 style ddname. Assume sequential file - cannot be a PDS
- * because I don't feel like trying to determine that right now.
- */
- if (!authorized_file(R)) {
- gbarf(R,"the GOPHER server won't read the DD for you");
- rc = FALSE;
- }
- else {
- strcpy(R->buffer,R->fileptr); /* still points to "DD:xxxxxxxx" */
- dstype = SEQ;
- rc = get_flat_file(R);
- }
- }
- else {
- /* Regular file name without ":" hack, or with invalid ":" hack.
- * Check to see that the file name is on our "official" list.
- */
- if (!authorized_file(R)) {
- gbarf(R,"the GOPHER server won't let you see the file");
- rc = FALSE;
- }
- else {
-
- /* Dynamically allocate data set and use generated ddname.
- * Note that we have to allocate the data set name to a ddname and
- * then open the ddname to prevent C/370 from barfing on otherwise
- * valid data set names like those with hyphens in them. But this
- * also lets us determine if the data set is sequential or a PDS.
- */
- strcpy(R->dsname,R->fileptr);
- dstype = GGMalloc(R->dsname,ddname,UNK,0);
- sprintf(R->buffer,"DD:%s",ddname);
- switch (dstype) {
- case SEQ: rc = get_flat_file(R); break;
- case PDS: rc = get_directory(R); break;
- default:
- printf("INVALID! requested:%s\n",R->fileptr);
- gbarf(R,"the GOPHER server couldn't allocate the file");
- rc = FALSE;
- }
- }
- }
-
- GGMunalc(ddname); /* free the ddname if set */
-
- if (!rc) {
- fflush(stdout);
- fflush(stderr);
- }
-
- return rc;
-
- }
-
- ./ ADD NAME=GGMPTX,SSI=01000029
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@PTX ")
- #pragma csect(static,"GG$PTX ")
- #include "gg.h"
-
- /****** Print the lines of server text. ******************************/
-
- void
- GGMptx(gp,ip)
- Rstruc ggcb *gp;
- Rstruc gopherinfo *ip;
- {
- FILE *pfp;
- struct texthdr *thp;
- struct textline *tp;
-
- thp = (ip ? &ip->thdr : &gp->thdr);
-
- pfp = stdout;
-
- /* Article must be specified (cannot be null). */
-
- for (tp=thp->first_text_line;tp;tp=tp->next) {
- if (tp->text_length >= 0) {
- char *p = tp->tab_expanded_text;
- while (*p) {
- if isprint(*p) fprintf(pfp,"%c",*p);
- else fprintf(pfp,"?");
- p++;
- }
- fprintf(pfp,"\n");
- }
- }
- fprintf(pfp,"\n");
-
- return;
-
- }
-
- ./ ADD NAME=GGMSOCKT,SSI=010B0052
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@SOCKT")
- #pragma csect(static,"GG$SOCKT")
- #include "gg.h"
-
- /****** Output one data line for the server. *************************/
-
- Bool
- GGMsockt(gp)
- Rstruc ggcb *gp;
- {
- int gopher_bytes;
- int writrc;
- char *s_buf;
- Bool procok;
- struct recvstruct *R;
-
- /* Before sending a request to the server, do a cleanup operation
- * to make sure that no more responses are coming from the server.
- */
-
- GGMesrvr(gp); /* End server read */
-
- /* If local mode, call server subtask processor with command. */
-
- if ((R=gp->recvp)) {
- if (!R->outfp) {
- CRIT1("Can't send data locally, non-socket not connected");
- return FALSE;
- }
- strncpy(R->buffer, gp->gopher_command, sizeof(R->buffer)-1);
- strcpy(R->myname, LOCAL_HOST_FROB); /* used by PDS feature */
-
- /* allocate SYSTSPRT file, used by REXX EXEC interface */
-
- if (GGMtso(
- "ALLOC FI(SYSTSPRT) T SP(100 100) REL REU DEL"
- " RECFM(V B) LRECL(1024) BLKSIZE(32760)"
- ) != 0) {
- fprintf(stderr,
- "Warning: Cannot allocate temporary SYSTSPRT file.\n");
- fprintf(stderr,
- " Some interfaces may not work properly.\n");
- }
-
- procok = GGMproc(R);
-
- /* free SYSTSPRT file, used by REXX EXEC interface */
-
- (void)GGMunalc("SYSTSPRT");
-
- /* Prepare to read from the beginning of the file */
-
- if (fseek(R->outfp, 0, SEEK_SET) != 0) {
- CRIT1("Can't reposition to start of local file");
- return FALSE;
- }
- return procok;
- }
-
- gopher_bytes = strlen(gp->gopher_command);
-
- memcpy(gp->client_buf,gp->gopher_command,gopher_bytes);
- gp->client_buf[gopher_bytes] = CARRIAGE_RETURN;
- gp->client_buf[gopher_bytes+1] = LINE_FEED;
-
- if (gp->receiving_text &&
- gopher_bytes == 1 &&
- gp->client_buf[0] == '.') {
- gp->receiving_text = FALSE;
- }
-
- if (gp->debug_mode)
- GGMdump(gp,"Writing to server",gp->client_buf,gopher_bytes+2);
-
- #ifdef MVS
- EBCDIC_TO_ASCII(gp->client_buf,gopher_bytes+2);
- #endif
-
- writrc = write(gp->socknum, gp->client_buf, gopher_bytes+2);
- if (writrc < 0) {
- gp->connection_broken = TRUE;
- CRIT2("TCP/IP error: write() failed to send data to server %s.",
- gp->ggserver);
- return FALSE;
- }
-
- /* Prepare server for read. */
-
- gp->server_has_something_pending = TRUE;
- gp->server_finished_replying = FALSE;
- gp->sending_text = FALSE;
- gp->dont_read = FALSE;
-
- return TRUE;
- }
-
- ./ ADD NAME=GGMSOPT,SSI=01000036
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@SOPT ")
- #pragma csect(static,"GG$SOPT ")
- #include "gg.h"
-
- #define BOOLOPTSET(A,B,C) \
- switch (A[0]) { \
- case 'n': \
- case 'N': B = FALSE; break; \
- case 'y': \
- case 'Y': B = TRUE; break; \
- case '\0': \
- default: B = C; break; \
- }
-
- /****** Set options that are stored in ISPF profile. *****************/
-
- void
- GGMsopt(gp,which)
- Rstruc ggcb *gp;
- enum user_option which;
- {
- int arrows;
- char ggextpow[ 4];
- char ggextpap[ 4];
- char ggscroll[ 4];
-
- if (which == OPTION_ALL) {
- GGMispf(gp, "VGET (GGMUPDTF GGEXTPOW GGEXTPOP GGSCROLL) PROFILE");
- }
-
- if (which == OPTION_ALL || which == OPTION_OTHER) {
-
- (void)GGMivget(gp,"GGEXTPOW ", ggextpow, sizeof(ggextpow));
- (void)GGMivget(gp,"GGEXTPAP ", ggextpap, sizeof(ggextpap));
-
- BOOLOPTSET(ggextpow, gp->warn_overwrite, TRUE);
- BOOLOPTSET(ggextpap, gp->warn_append, TRUE);
-
- }
-
- if (which == OPTION_ALL || which == OPTION_VIEW) {
-
- (void)GGMivget(gp,"GGSCROLL ", ggscroll, sizeof(ggscroll));
-
- BOOLOPTSET(ggscroll, gp->autoscroll, TRUE);
-
- }
-
- return;
- }
-
- ./ ADD NAME=GGMSSRVR,SSI=01010032
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@SSRVR")
- #pragma csect(static,"GG$SSRVR")
- #include "gg.h"
-
- /****** Start server read. *******************************************/
-
- void
- GGMssrvr(gp)
- Rstruc ggcb *gp;
- {
-
- gp->server_has_something_pending = TRUE;
- gp->server_finished_replying = FALSE;
- gp->sending_text = FALSE;
- gp->dont_read = FALSE;
-
- return;
-
- }
-
- ./ ADD NAME=GGMTNET,SSI=01050009
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@TNET ")
- #pragma csect(static,"GG$TNET ")
- #include "gg.h"
-
- /****** Gopher TELNET interface. *************************************/
-
- Bool
- GGMtnet(gp,ip,as_file)
- Rstruc ggcb *gp;
- Rstruc gopherinfo *ip;
- Fool as_file;
- {
- int tsorc;
- char tsocmd[256];
-
- if (as_file) {
- ERR1("TELNET interface cannot be viewed as a file.");
- return FALSE;
- }
-
- GGMispf(gp,"CONTROL DISPLAY LINE");
-
- fprintf(stderr,"Note: Login as user: %s\n\n", ip->path);
-
- if (ip->port==0) sprintf(tsocmd,"%s %s",TELNET_COMMAND_NAME,ip->host);
- else sprintf(tsocmd,"%s %s %d",TELNET_COMMAND_NAME,ip->host,ip->port);
-
- if ((tsorc = GGMtso(tsocmd)) != 0) {
- ERR3("%s command returned code %d", TELNET_COMMAND_NAME, tsorc);
- }
-
- GGMispf(gp,"CONTROL DISPLAY REFRESH");
-
- return TRUE;
- }
-
- ./ ADD NAME=GGMTSO,SSI=01000051
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- /********************************************************************/
- /* */
- /* Thanks to Michael Van Norman for this code. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@TSO ")
- #pragma csect(static,"GG$TSO ")
- #include "gg.h"
-
- #pragma linkage(ikjeftsr,OS)
-
- #define _IKJEFTSR_FLAGS_AUTH 0x00000000
- #define _IKJEFTSR_FLAGS_COMMAND 0x00000001
- #define _IKJEFTSR_FLAGS_DUMP 0x00000100
- #define _IKJEFTSR_FLAGS_NODUMP 0x00000000
- #define _IKJEFTSR_FLAGS_PROGRAM 0x00000002
- #define _IKJEFTSR_FLAGS_UNAUTH 0x00010000
-
- /****** Issue TSO command. *******************************************/
-
- int
- GGMtso(command)
- char *command;
- {
- int flags = _IKJEFTSR_FLAGS_COMMAND +
- _IKJEFTSR_FLAGS_UNAUTH;
- int commandLength = strlen(command);
- int rc = 0;
- int returnCode = 0;
- int reasonCode = 0;
- int abendCode = 0;
-
- static int (*ikjeftsr)() = NULL;
-
- if (!ikjeftsr) {
- int tsoEntryAddress;
-
- tsoEntryAddress = 0x00000010; /* Address of CVT */
- tsoEntryAddress = *(int *)(tsoEntryAddress);
- tsoEntryAddress += 0x9C;/* /* Offset of TVT in CVT */
- tsoEntryAddress = *(int *)(tsoEntryAddress);
- tsoEntryAddress += 0x10;/* /* TSVTASF-TSVT (from IKJTSVT) */
- tsoEntryAddress = *(int *)(tsoEntryAddress);
- ikjeftsr = (int (*)())(tsoEntryAddress);
- }
-
- if (!ikjeftsr) {
- fprintf(stderr,
- "Cannot execute TSO commands, can't fetch IKJEFTSR.\n");
- return -2;
- }
-
- rc = (*ikjeftsr)(&flags, command, &commandLength,
- &returnCode, &reasonCode,
- (int *)((int)(&abendCode) | 0x80000000));
-
- if (rc != 0) {
- if (rc > 4) {
- fprintf(stderr,"Command failed:%s\n",command);
- if (rc == 20 && reasonCode == 40)
- fprintf(stderr,"Command was not found.\n");
- else fprintf(stderr,
- "rc=%d,returncode=%d,reasoncode=%d,abendcode=%8.8x\n",
- rc, returnCode, reasonCode, abendCode);
- }
- if (abendCode != 0) rc = -1;
- else rc = returnCode;
- }
-
- return rc;
- }
-
- ./ ADD NAME=GGMTYPE,SSI=01040025
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@TYPE ")
- #pragma csect(static,"GG$TYPE ")
- #include "gg.h"
-
- /*********************************************************************/
-
- char *
- GGMtype(gophertype t)
- {
-
- switch (t) {
- case GOPHER_FILE: return "File ";
- case GOPHER_DIRECTORY: return "Directory";
- case GOPHER_CSO: return "Cso ";
- case GOPHER_ERROR: return "Error ";
- case GOPHER_MAC_BINHEX: return "Binhex ";
- case GOPHER_DOS_BINARCH: return "Binarch ";
- case GOPHER_UUENCODE: return "Uuencode ";
- case GOPHER_WAIS: return "Index ";
- case GOPHER_TELNET: return "Telnet ";
- case GOPHER_TN3270: return "TN3270 ";
- case GOPHER_BINARY: return "Binary ";
- case GOPHER_REDUNDANT: return "Redundant";
- case GOPHER_WHOIS: return "Whois ";
- default: return "Unknown ";
- }
- }
-
- ./ ADD NAME=GGMUNALC,SSI=01000040
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@UNALC")
- #pragma csect(static,"GG$UNALC")
- #include "gg.h"
-
- /****** Unallocate a data set. ***************************************/
-
- Bool
- GGMunalc(ddname)
- char *ddname;
- {
- __S99parms stuff99; /* The manual has it wrong. No "struct". */
- int rc;
- char *cp;
- TEXTUNIT *tu [2];
- TEXTUNIT tu_ddn;
- TEXTUNIT tu_una;
-
- if (!ddname ||
- !*ddname) return TRUE; /* if no ddname to free, do nothing */
-
- memset((char *)&stuff99,0,sizeof(__S99parms));
-
- stuff99.__S99RBLN = 20;
- stuff99.__S99VERB = S99VRBUN;
- stuff99.__S99FLAG1 = 0;
- stuff99.__S99ERROR = 0;
- stuff99.__S99INFO = 0;
- stuff99.__S99TXTPP = tu;
- stuff99.__S99FLAG2 = 0;
-
- tu[0] = &tu_ddn;
- tu[1] = &tu_una;
- *(int *)&tu[1] |= 0x80000000;
-
- tu_ddn.key = DUNDDNAM;
- tu_ddn.num = 1;
- tu_ddn.ent.len = strlen(ddname);
- strcpy(tu_ddn.ent.prm,ddname);
-
- tu_una.key = DUNUNALC;
- tu_una.num = 0;
-
- for (cp=tu_ddn.ent.prm; *cp; cp++) *cp = toupper(*cp);
-
- rc = svc99(&stuff99);
-
- if (rc == 0) return TRUE;
- else if (stuff99.__S99ERROR == 0x0438) /* not freed, is not allocated*/
- return TRUE;
- else {
- GGMdfail(rc,&stuff99);
- return FALSE;
- }
- }
-
- ./ ADD NAME=GGMVTX,SSI=01050014
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@VTX ")
- #pragma csect(static,"GG$VTX ")
- #include "gg.h"
-
- /****** BRIF fakeout. ************************************************/
-
- static void
- fake_out_for_brif(fpp,codebuf)
- void **fpp;
- char *codebuf;
-
- #ifndef I370
-
- /* The purpose of this is to put a wrapper around the actual
- function pointed to by the argument, so that FORTRAN-style
- return codes (in register 0) get put into register 15.
-
- Source code:
-
- USING *,15
- ST 14,save_14
- L 15,realcode
- DROP 15
- BALR 14,15
- USING *,14
- L 14,save_14
- DROP 14
- LR 15,0
- BR 14
- SPACE 1
- save_14 DS F
- realcode DS F
-
- *** Warning: As written, this fake-out code is not reentrant. ***
-
- */
-
- {
- static char fake_out_code[32] = {
- 0x50,0xE0,0xF0,0x14,0x58,0xF0,0xF0,0x18,
- 0x05,0xEF,0x58,0xE0,0xE0,0x0A,0x18,0xF0,
- 0x07,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
- };
-
- memcpy(codebuf,fake_out_code,32);
- memcpy(codebuf+0x18,(char *)fpp,4);
-
- #else
-
- /* The purpose of this is to put a wrapper around the actual
- function pointed to by the argument, so that the C Runtime
- Anchor Block pointer (in register 12) can be saved/restored.
- */
-
- {
- #define FAKE_BUF_SIZE 48 /* */
- static short fake_out_code[FAKE_BUF_SIZE/2] =
- { /* USING *,15 */
- 0x50C0,0xF020, /* +00 ST 14,save_12 */
- 0x50E0,0xF024, /* +04 ST 12,save_14 */
- 0x58C0,0xF02C, /* +08 L 12,crab */
- 0x58F0,0xF028, /* +0C L 15,realcode */
- /* DROP 15 */
- 0x58F0,0xF000, /* +10 L 15,0(,15) */
- 0x05EF, /* +14 BALR 14,15 */
- /* USING *,14 */
- 0x58C0,0xE00A, /* +16 L 12,save_12 */
- 0x58E0,0xE00E, /* +1A L 14,save_14 */
- /* DROP 14 */
- 0x07FE, /* +1E BR 14 */
- 0x0000,0x0000, /* +20 save_12 */
- 0x0000,0x0000, /* +24 save_14 */
- 0x0000,0x0000, /* +28 realcode */
- 0x0000,0x0000 /* +2C crab */
- };
-
- memcpy( codebuf, fake_out_code, FAKE_BUF_SIZE );
- memcpy( codebuf+0x28, (char *)fpp, 4 );
- _ldregs( R2, codebuf+0x2C ), /* get -> crab in fakeout buff */
- _code ( 0, 0x50C0, 0x2000 ); /* save -> CRAB */
-
- #endif
-
- *fpp = (void *)codebuf;
-
- return;
-
- }
-
- /****** Print text lines. ********************************************/
-
- static void
- print_text_lines(fp,textp)
- FILE *fp;
- struct textline *textp;
- {
- struct textline *tp;
- char *p;
-
- for (tp=textp; tp; tp=tp->next) {
- if (tp->text_length >= 0) {
- p = tp->tab_expanded_text;
- while (*p) {
- if isprint(*p) fprintf(fp,"%c",*p);
- else fprintf(fp,"?");
- p++;
- }
- fprintf(fp,"\n");
- }
- }
- fprintf(fp,"\n");
-
- return;
- }
-
- /****** View the lines of text retrieved from the server. ************/
-
- Bool
- GGMvtx(gp,ip,as_file)
- Rstruc ggcb *gp;
- Rstruc gopherinfo *ip;
- Fool as_file; /* ignored */
- {
- int brif_max_reclen;
- int i;
- char *p;
- char *q;
- struct texthdr *texthdrp;
- void *dialog_data_ptr;
- void *read_function_ptr;
- void *command_function_ptr;
- char read_fakeout_buffer [32];
- char command_fakeout_buffer [32];
- char brif_title [81];
-
- texthdrp = (ip ? &ip->thdr : &gp->thdr);
-
- if (gp->brifp) {
- printf("Cannot use ISPF BROWSE now, displaying in line mode:\n\n");
- print_text_lines(stdout,texthdrp->first_text_line);
- return TRUE;
- }
-
- gp->brifp = texthdrp;
-
- gp->brif_previous_recno = -1;
-
- if (!ip) sprintf(brif_title, "GopherServer:%s ",gp->ggserver);
- else {
- /* BRIF doesn't like blanks in the title */
- for (p=ip->desc,q=brif_title,i=sizeof(brif_title)-1;
- i > 0 && *p;
- p++,q++,i--) {
- *q = (*p == ' ' ? '_' : *p);
- }
- *q = ' ';
- *(q+1) = '\0';
- }
-
- brif_max_reclen = gp->brifp->text_max_tab_expanded_length;
- dialog_data_ptr = (void *)gp;
- read_function_ptr = (void *)&GGMbrifr;
- command_function_ptr = (void *)&GGMbrifc;
-
- fake_out_for_brif(&read_function_ptr,read_fakeout_buffer);
- fake_out_for_brif(&command_function_ptr,command_fakeout_buffer);
-
- if (gp->test_mode) {
- printf("Here are the %d lines BRIF should be displaying:\n\n",
- gp->brifp->text_line_count);
- print_text_lines(stdout,gp->brifp->first_text_line);
- gp->brifp = NULL;
- return TRUE;
- }
-
- if (gp->setmsg) {
- (void)GGMispf(gp,"SETMSG MSG(ISRZ002)");
- gp->setmsg = FALSE;
- }
-
- gp->ispfrc = ISPLINK("BRIF ",
- brif_title,
- "V ", /* variable record format */
- &brif_max_reclen,
- &read_function_ptr,
- &command_function_ptr,
- &dialog_data_ptr,
- " ", /* use IBM's browse panel */
- " ", /* no format */
- "NO "); /* default sbcs data */
-
- gp->brifp = NULL;
-
- switch (gp->ispfrc) {
- case 0:
- break;
- case 12:
- ERR1("There is no data returned from the gopher host to be browsed.");
- break;
- case 16:
- break;
- default:
- GGMierr(gp); /* handle ISPF error */
- break;
- }
-
- return TRUE;
- }
-
- ./ ADD NAME=GGMWAIS,SSI=01080054
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@WAIS ")
- #pragma csect(static,"GG$WAIS ")
- #include "gg.h"
-
- /****** Gopher WAIS interface. *************************************/
-
- Bool
- GGMwais(gp,ip,as_file)
- Rstruc ggcb *gp;
- Rstruc gopherinfo *ip;
- Fool as_file;
- {
- char *lp;
- char ggwaisq[256];
-
- strcpy(gp->ggserver,ip->host); /* Specify server to connect to */
-
- strcpy(ggwaisq,"");
-
- GGMispf(gp,"VGET (GGWAISQ) PROFILE");
-
- if (GGMdispl(gp,"GGMPWAIS") > 0) return FALSE;
-
- GGMivget(gp,"GGWAISQ ",ggwaisq, sizeof(ggwaisq));
-
- if (!*ip->path) strcpy(gp->gopher_command, ggwaisq);
- else sprintf(gp->gopher_command,"%s\t%s",ip->path,ggwaisq);
-
- gp->ginfo = ip;
- gp->receiving_text = FALSE;
-
- if (!GGMconn(gp)) return FALSE; /* Connect to gopher server */
-
- if (!GGMsockt(gp)) return FALSE; /* Send socket command to server */
-
- GGMclrtx(gp,ip); /* Clear text */
-
- gp->receiving_text = TRUE;
-
- do {
- if (GGMgsrvl(gp,&lp,TRUE)) { /* Get server line */
- if (lp) {
- (void)GGMouttx(gp,lp,ip); /* Output text line */
- }
- }
- } while (lp); /* until no more lines */
-
- if (gp->time_to_go_home) {
- WARN2("No data available from server %s.\n",gp->ggserver);
- return FALSE;
- }
-
- if (gp->connected_to_server) {
- (void)GGMdisc(gp); /* Disconnect from gopher server */
- }
-
- GGMdir(gp,ip,as_file); /* display entries returned from WAIS server */
-
- return TRUE;
-
- }
-
- ./ ADD NAME=GGMWHOIS,SSI=01030030
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@WHOIS")
- #pragma csect(static,"GG$WHOIS")
- #include "gg.h"
-
- /****** Gopher WHOIS/FINGER interface. *****************************/
-
- Bool
- GGMwhois(gp,ip,as_file)
- Rstruc ggcb *gp;
- Rstruc gopherinfo *ip;
- Fool as_file; /* ignored */
- {
- char *lp;
- Bool got_some;
- char ggwhoisq[256];
-
- strcpy(gp->ggserver,ip->host); /* Specify server to connect to */
-
- strcpy(ggwhoisq,"");
-
- GGMispf(gp,"VGET (GGWHOISQ) PROFILE");
-
- if (GGMdispl(gp,"GGMPWHOI") > 0) return FALSE;
-
- GGMivget(gp,"GGWHOISQ ",ggwhoisq, sizeof(ggwhoisq));
-
- if (!*ip->path) strcpy(gp->gopher_command, ggwhoisq);
- else sprintf(gp->gopher_command,"%s\t%s",ip->path,ggwhoisq);
-
- gp->ginfo = ip;
- gp->receiving_text = FALSE;
-
- if (!GGMconn(gp)) return FALSE; /* Connect to gopher server */
-
- if (!GGMsockt(gp)) return FALSE; /* Send socket command to server */
-
- GGMclrtx(gp,ip); /* Clear text */
-
- gp->receiving_text = TRUE;
- got_some = FALSE;
- do {
- if (GGMgsrvl(gp,&lp,TRUE)) { /* Get server line */
- if (lp) {
- got_some = TRUE;
- (void)GGMouttx(gp,lp,ip); /* Output text line */
- }
- }
- } while (lp); /* until no more lines */
-
- if (!got_some) {
- WARN2("No data available from server %s.\n",gp->ggserver);
- return FALSE;
- }
-
- if (gp->connected_to_server) {
- (void)GGMdisc(gp); /* Disconnect from gopher server */
- }
-
- GGMvtx(gp,ip,as_file); /* display text from WHOIS/FINGER server */
-
- return TRUE;
-
- }
-
- ./ ADD NAME=GGMXTX,SSI=01050051
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GG@XTX ")
- #pragma csect(static,"GG$XTX ")
- #include "gg.h"
-
- /****** Extract the lines of server text into a data set. ************/
-
- Bool
- GGMxtx(gp,ip)
- Rstruc ggcb *gp;
- Rstruc gopherinfo *ip;
- {
- FILE *xfp;
- struct texthdr *thp;
- struct textline *tp;
- struct extraction *ep;
- int l;
- char *cp;
- char formatted_number [11];
- struct extraction the_extraction;
-
- thp = (ip ? &ip->thdr : &gp->thdr);
-
- /* Set article data for message. */
-
- if (ip) {
- sprintf(formatted_number,"%d",ip->type);
- (void)GGMivput(gp,"GGTNUM ", formatted_number, -1);
- (void)GGMivput(gp,"GGTSUBJ ", ip->desc, -1);
- }
-
- if (gp->extract_file) {
- (void)GGMispf(gp,"CONTROL DISPLAY LOCK");
- (void)GGMispf(gp,"DISPLAY PANEL(GGMLEXN2)");
- xfp = gp->extract_file;
- }
- else {
-
- ep = &the_extraction;
- memset(ep,0,sizeof(struct extraction));
- ep->mode = SEQ;
- strcpy(ep->panelname,"GGMPEXDS");
-
- if (!((xfp=GGMgetds(gp,ep)))) return FALSE;
-
- gp->extract_tab_expanding = ep->tab_expanding;
- gp->extract_appending = ep->appending;
- gp->extract_blank_before_separator = ep->blanking;
- gp->extract_separator_line = ep->separator;
- }
-
- /* If append mode, and a separator line was specified, use it. */
-
- gp->extract_write_error = FALSE;
- gp->extract_close_error = FALSE;
-
- while (gp->extract_appending && gp->extract_separator_line &&
- *gp->extract_separator_line) {
- if (fprintf(xfp,"%s\n",gp->extract_separator_line) < 0) {
- gp->extract_write_error = TRUE; break;
- }
- if (gp->extract_blank_before_separator) {
- if (fprintf(xfp,"\n") < 0) {
- gp->extract_write_error = TRUE; break;
- }
- }
- break;
- }
- for (tp = thp->first_text_line;
- tp && !gp->extract_write_error;
- tp = tp->next) {
- if (tp->text_length == 0) {
- if (fputc('\n',xfp) == EOF) {
- gp->extract_write_error = TRUE; break;
- }
- }
- else if (tp->text_length > 0) {
- if (gp->extract_tab_expanding) {
- cp = tp->tab_expanded_text;
- l = tp->tab_expanded_text_length;
- }
- else {
- cp = tp->text;
- l = tp->text_length;
- }
- for (; l > 0; cp += 251, l -= 251) {
- fwrite(cp,(l>251 ? 251 : l),1,xfp);
- if (ferror(xfp)) {
- gp->extract_write_error = TRUE; break;
- }
- if (fputc('\n',xfp) == EOF) {
- gp->extract_write_error = TRUE; break;
- }
- }
- }
- }
-
- if (!gp->extract_write_error && ferror(xfp))
- gp->extract_write_error = TRUE;
-
- if (!gp->extract_appending || !gp->extract_file) {
- if (fclose(xfp) < 0) {
- /* perror(nnexdsn); */
- ERR2("An error occurred closing data set %s.", ep->dsname);
- gp->extract_close_error = TRUE;
- return FALSE;
- }
- }
-
- if (!gp->extract_file) {
- if (gp->extract_write_error) {
- ERR2("An error occurred writing to data set %s.", ep->dsname);
- gp->extract_write_error = TRUE;
- }
- else if (ip) {
- WARN2("Current item extracted into file %s.",
- ep->dsname);
- }
- else {
- WARN2("Displayed text has been extracted into file %s.",
- ep->dsname);
- }
- }
- if (gp->extract_write_error) return FALSE;
- else return TRUE;
- }
-
- ./ ADD NAME=GGSERVER,SSI=01240010
- /*
- ***********************************************************************
- * *
- * GOPHER server, based on the simple TCP/IP server from Shawn Hart at *
- * the University of Delaware. *
- * *
- ***********************************************************************
- *
- * This server follows the GOPHER protocols defined by UMN.
- * For more information, see the ANONYMOUS FTP site at
- * BOOMBOX.MICRO.UMN.EDU.
- *
- ***********************************************************************
- *
- * November 1992 - parameters may be passed to the server:
- *
- * -d run in debug mode
- *
- ***********************************************************************
- *
- * December 1992 - support for SNS/TCPAccess compilation
- *
- ***********************************************************************
- */
-
- #pragma csect(code, "GG@ERVER")
- #pragma csect(static,"GG$ERVER")
- #include "gg.h" /* All system file includes needed. */
-
- /********************************************************************/
-
- static int
- tcpsetup(int port,
- int qlen,
- FILE *debugfp)
- {
- int tinitrc; /* loop counter*/
- int sockfd; /* loop counter*/
- int x; /* loop counter*/
- struct linger l; /* linger for setsockopt */
- struct sockaddr_in server; /*server address information */
-
- /* initialize the MTF environment. */
-
- if (debugfp) {
- fprintf(debugfp,"tinit...\n");
- fflush(debugfp);
- }
-
- tinitrc = tinit("GGSTASK", MTF_TASKS);
-
- if (tinitrc != MTF_OK) {
- GGMmtfer(tinitrc, "TINIT");
- return -1;
- }
-
- /* open a TCP socket... */
-
- if (debugfp) {
- fprintf(debugfp,"socket...\n");
- fflush(debugfp);
- }
-
- if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- REPORT_TCP_ERROR("SOCKET - ");
- return -1;
- };
-
- /* set the linger option on so we wait for data to be sent... */
-
- l.l_onoff = 1;
- l.l_linger =100; /* wait 100 seconds before giving up */
-
- if (debugfp) {
- fprintf(debugfp,"setsockopt (%d, SO_LINGER)...\n",sockfd);
- fflush(debugfp);
- }
-
- if (setsockopt(sockfd,SOL_SOCKET,SO_LINGER,(char *)&l,sizeof(l))
- < 0) {
- REPORT_TCP_ERROR("SETSOCKOPT - ");
- return -1;
- }
-
- /* now bind our local address so that the client can send to us */
-
- memset((char *)&server, 0, sizeof(server));
- server.sin_family = AF_INET;
- server.sin_addr.s_addr = INADDR_ANY;
- server.sin_port = htons(port);
-
- if (debugfp) {
- fprintf(debugfp,"bind (%d)...\n",sockfd);
- fflush(debugfp);
- }
-
- if (Bind(sockfd, &server, sizeof(server)) < 0) {
- REPORT_TCP_ERROR("BIND - ");
- return -1;
- }
-
- /* now set length of the connection queue... */
-
- if (debugfp) {
- fprintf(debugfp,"listen (sockfd=%d, qlen=%d)...\n",sockfd,qlen);
- fflush(debugfp);
- }
-
- if (listen(sockfd,qlen) != 0) {
- REPORT_TCP_ERROR("LISTEN -");
- return -1;
- }
-
- return sockfd;
-
- }
-
-
- /********************************************************************/
- /*
- * This routine waits for an exception on the socket. When one
- * occurs (by a subtask's "TAKESOCKET"!) we'll close our (the main
- * task's) connection to it.
- *
- * INPUT s pointer to socket descripter.
- * OUTPUT rc -1 = connection timed out...
- * 0 = an excption occured!
- */
- /********************************************************************/
-
- #ifdef SNSTCPIP
-
- static int
- closesock(int newsockfd,
- FILE *debugfp)
- {
- if (debugfp) {
- fprintf(debugfp,"close (%d)...\n",newsockfd);
- fflush(debugfp);
- }
-
- if (close(newsockfd) < 0) REPORT_TCP_ERROR("CLOSE -");
- return 0;
- }
-
- #else
-
- static int
- closesock(int newsockfd,
- FILE *debugfp)
- {
- int temps;
- struct sockaddr clientaddress;
- int addrlen;
- int maxfdpl;
- struct fd_set readmask;
- struct fd_set writmask;
- struct fd_set exepmask;
- int rc;
- struct timeval time;
-
- temps = newsockfd;
- time.tv_sec = CONNECT_TIME_OUT;
- time.tv_usec = 0;
- maxfdpl = temps + 1;
-
- FD_ZERO(&readmask);
- FD_ZERO(&writmask);
- FD_ZERO(&exepmask);
- FD_SET(temps, &exepmask);
-
- if (debugfp) {
- fprintf(debugfp,"select (maxfdpl=%d)...\n",maxfdpl);
- fflush(debugfp);
- }
-
- rc = select(maxfdpl, &readmask, &writmask, &exepmask, &time);
-
- if (rc < 0) {
- REPORT_TCP_ERROR("SELECT - ");
- return rc;
- }
- else {
- if (rc == 0) fprintf(stdout,"The GIVESOCKET timed out!\n");
-
- if (debugfp) {
- fprintf(debugfp,"close (%d)...\n",newsockfd);
- fflush(debugfp);
- }
-
- if (close(newsockfd) < 0) REPORT_TCP_ERROR("CLOSE -");
- return rc;
- }
- }
-
- #endif
-
- /********************************************************************/
- /*
- * This routine starts a subtask, passing control of a socket
- * to it. It then waits for the subtask to take the socket and
- * then closes the socket.
- *
- * INPUT: newsockfd - socket descriptor to give to subtask.
- */
- /********************************************************************/
-
- static Bool
- spawn(
- int newsockfd,
- FILE *debugfp)
- {
- int tschedrc;
- #ifdef SNSTCPIP
- unsigned long token;
- #else
- struct clientid clid;
- char mysname[8];
- #endif
-
- if (debugfp) {
- fprintf(debugfp,"getclientid...\n");
- fflush(debugfp);
- }
-
- #ifdef SNSTCPIP
-
- token = closepass(newsockfd);
- if (debugfp) {
- fprintf(debugfp,"token = %X\n",token);
- fflush(debugfp);
- }
-
- #else
-
- memset(&clid,0,sizeof(clid));
- if(getclientid(AF_INET,&clid) < 0) {
- REPORT_TCP_ERROR("GETCLIENTID");
- return FALSE;
- }
-
- if (debugfp) {
- fprintf(debugfp,"client name = %8.8s, subtaskname = %8.8s\n",
- clid.name, clid.subtaskname);
- fflush(debugfp);
- }
-
- clid.domain = AF_INET;
- memcpy(mysname,clid.subtaskname,8);
- memcpy(clid.subtaskname," ",8);
-
- if (debugfp) {
- fprintf(debugfp,"givesocket (%d)...\n",newsockfd);
- fflush(debugfp);
- }
-
- if(givesocket(newsockfd,&clid) != 0) {
- REPORT_TCP_ERROR("GIVESOCKET");
- return FALSE;
- }
- memcpy(clid.subtaskname,mysname,8);
-
- if (debugfp) {
- fprintf(debugfp,"client name = %8.8s, subtaskname = %8.8s\n",
- clid.name, clid.subtaskname);
- fflush(debugfp);
- }
-
- #endif
-
- if (debugfp) {
- fprintf(debugfp,"tsched...\n");
- fflush(debugfp);
- }
-
- tschedrc = tsched(MTF_ANY,"GGSRECV",
- #ifdef SNSTCPIP
- token,
- #else
- newsockfd,
- clid,
- #endif
- (debugfp ? 1 : 0));
-
- if (debugfp) {
- fprintf(debugfp,"tsched completed...rc=%d\n",tschedrc);
- fflush(debugfp);
- }
-
- if (tschedrc != 0) {
- GGMmtfer(tschedrc,"TSCHED");
- return FALSE;
- }
-
- if (closesock(newsockfd,debugfp) < 0) {
- REPORT_TCP_ERROR("close socket");
- return FALSE;
- }
-
- return TRUE;
-
- }
-
- /******************************************************************/
-
- int
- main(int argc,
- char **argv)
- {
- int trc; /* return code */
- int x; /* loop counter*/
- int sockfd; /* connection socket...*/
- int newsockfd; /* new connection socket...*/
- int clientlen; /* new connection socket...*/
- int i;
- char *p;
- FILE *debugfp;
- struct sockaddr_in client; /* client address information */
- #ifndef SNSTCPIP
- struct clientid clid; /* client info for givesocket */
- #endif
- char buffer[255]; /* buffer for input/output*/
-
- /******************************************************************/
- /* Process server parameters. */
- /******************************************************************/
-
- debugfp = NULL;
-
- for (i = 1; i < argc; i++) {
- p = argv[i];
- if (*p == '-') {
- while (*++p) {
- switch (toupper(*p)) {
- case 'D': debugfp = fopen("dd:ggdebug","w");
- break;
- default: break;
- }
- }
- }
- }
-
- /******************************************************************/
- /* set up the connection to the socket... */
- /******************************************************************/
-
- sockfd = tcpsetup(SERV_TCP_PORT,TCP_QUEUE_LENGTH,debugfp);
- if (sockfd < 0) {
- fprintf(stdout,"Could not set up the TCP/IP environment!\n");
- exit(16);
- }
-
- /******************************************************************/
- /* Now loop, waiting for a connection request. */
- /******************************************************************/
-
- clientlen = sizeof(client);
- x = 0;
- for (;;) {
-
- if (debugfp) {
- fprintf(debugfp,"accept (%d)...\n",sockfd);
- fflush(debugfp);
- }
-
- if ((newsockfd=Accept(sockfd,&client,&clientlen)) == -1) {
- REPORT_TCP_ERROR("ACCEPT - ");
- exit(8);
- }
- if (debugfp) {
- fprintf(debugfp,"newsockfd=%d...\n",newsockfd);
- fflush(debugfp);
- }
-
- x++;
- if (!spawn(newsockfd,debugfp)) {
- fprintf(stdout,"spawn failed for socket %d\n",newsockfd);
- exit(8);
- }
- else {
- if (debugfp) {
- fprintf(debugfp,"spawn OK for socket %d\n",newsockfd);
- fflush(debugfp);
- }
- }
- }
-
- /******************************************************************/
- /* Wait for all pending tasks to complete (should never */
- /* run, since I haven't added PURGE support yet...) */
- /* then shut down subtasks. */
- /******************************************************************/
-
- if (debugfp) {
- fprintf(debugfp,"tsyncro...\n");
- fflush(debugfp);
- }
-
- trc = tsyncro(MTF_ALL);
- if (trc != 0) {
- GGMmtfer(trc,"TSYNCRO");
- }
-
- if (debugfp) {
- fprintf(debugfp,"tterm...\n");
- fflush(debugfp);
- }
-
- trc = tterm();
- if (trc != 4) {
- GGMmtfer(trc,"TTERM");
- exit(8);
- }
-
- if (debugfp) fclose(debugfp);
-
- exit(0);
-
- }
- ./ ADD NAME=GGSTASK,SSI=01630058
-
- /********************************************************************/
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- #pragma csect(code, "GGSTASK ")
- #pragma csect(static,"GG$TASK ")
-
- #include "gg.h"
-
- /*=================================================================*/
-
- /*******************************************************************/
- /* */
- /* this is a debugging routine; it looks at the status of a */
- /* socket. */
- /*******************************************************************/
-
- static void
- lookatsocket(int sockfd)
- {
- int rc; /* return code */
- int length; /* length variable */
- int option;
- int x;
- struct linger l; /* linger structure */
- char buffer[RBUFSIZE];
-
- length = sizeof(l);
- if (Getsockopt(sockfd,SOL_SOCKET, SO_LINGER,&l,&length)==0) {
- printf("l_onoff=%d\n",l.l_onoff);
- printf("l_linger=%d\n",l.l_linger);
- }
- else REPORT_TCP_ERROR("GETSOCKOPT");
-
- length = sizeof(option);
- if (Getsockopt(sockfd,SOL_SOCKET, SO_ERROR,&option,&length)==0) {
- printf("so_error=%d\n",option);
- }
- else REPORT_TCP_ERROR("GETSOCKOPT");
-
- if (fcntl(sockfd,F_SETFL,FNDELAY)!=0) REPORT_TCP_ERROR("FCNTL");
-
- length = recv(sockfd,buffer,sizeof(buffer)-1,0);
- if (length == -1) {
- if (errno != EWOULDBLOCK) REPORT_TCP_ERROR("recv");
- }
- else {
- buffer[sizeof(buffer)-1] = 0;
- printf("buffer =%s\n",buffer);
- for (x=0;x<length;x++) printf("%x ",buffer[x]);
- printf("\n");
- }
-
- }
-
- /*******************************************************************/
-
- /**************************************************************/
- /* this routine processes the data once a connection */
- /* has been accepted. It just takes the data sent by the */
- /* client and prints it to sysprint, then sends it back */
- /* to the client. */
- /* */
- /* INPUT: newsockfd - socket descriptor */
- /* clid - takesocket structure... */
- /**************************************************************/
-
- void
- GGSrecv(
- #ifdef SNSTCPIP
- unsigned long token,
- #else
- int newsockfd,
- struct clientid clid,
- #endif
- int is_debug
- )
- {
- struct recvstruct *R;
- struct hostent *hostentp;
- char *bufptr; /* pointer into buffer strings */
- char *hp;
- char **halias;
- int retcode; /* return code */
- int len; /* length of the buffer we're sent */
- int x; /* loop counter */
- int addrlen; /* length of client address socket */
- int hostlen;
- int domslen;
- struct sockaddr_in clientaddress; /* address of client */
- struct recvstruct r;
- time_t timeval;
- struct tm *tmp;
- char outbuf[RBUFSIZE]; /* hold an output string */
- char timestamp[20];
-
- memset(&r, 0, sizeof(struct recvstruct));
- R = &r;
-
- #ifdef SNSTCPIP
-
- if (is_debug) {
- fprintf(stdout,"openold (token=%X)...\n",token);
- fflush(stdout);
- }
- s0skcfg.exitfunc = NULL; /* Set exit address to NULL */
- R->sockfd = openold(token);
- if (is_debug) {
- fprintf(stdout,"sockfd from openold is %d\n", R->sockfd);
- fflush(stdout);
- }
- if(R->sockfd < 0) {
- REPORT_TCP_ERROR("OPENOLD");
- fflush(stderr);
- return;
- }
-
- #else
-
- if (is_debug) {
- fprintf(stdout,"takesocket (newsockfd=%d)...\n",newsockfd);
- fprintf(stdout,"name is %8.8s, subtaskname is %8.8s\n",
- clid.name,clid.subtaskname);
- fflush(stdout);
- }
-
- R->sockfd = takesocket(&clid,newsockfd);
- if (is_debug) {
- fprintf(stdout,"sockfd from takesocket is %d\n", R->sockfd);
- fflush(stdout);
- }
- if(R->sockfd < 0) {
- REPORT_TCP_ERROR("TAKESOCKET");
- return;
- }
-
- #endif
-
- time(&timeval);
- tmp = localtime(&timeval);
- sprintf(timestamp,"%2.2d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d",
- tmp->tm_mon + 1, tmp->tm_mday, tmp->tm_year,
- tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
- if (is_debug) {
- fprintf(stdout,"getpeername...\n");
- fflush(stdout);
- }
-
- addrlen = sizeof(clientaddress);
- if(Getpeername(R->sockfd,&clientaddress,&addrlen)!=0) {
- REPORT_TCP_ERROR("GETPEERNAME");
- printf("could not determine client address for socket %d\n",
- R->sockfd);
- }
-
- /* Try to get the name of the client host. */
-
- strcpy(R->hostname,"{UNKNOWN HOST NAME}");
-
- if (is_debug) {
- fprintf(stdout,"gethostbyaddr...\n");
- fflush(stdout);
- }
-
- hostentp = Gethostbyaddr(&clientaddress.sin_addr,
- sizeof(clientaddress.sin_addr),
- AF_INET);
-
- if (hostentp && hostentp->h_name) {
- memcpy(&R->clienthostent, hostentp, sizeof(struct hostent));
- strcpy(R->hostname,hostentp->h_name);
- uppercase_in_place(R->hostname);
- }
-
- strcpy(R->hosttest,R->hostname);
-
- hostlen = strlen(R->hosttest);
- domslen = sizeof(MY_DOMAIN_SUFFIX) - 1;
- if (hostlen > domslen) {
- hp = R->hosttest + hostlen - domslen;
- if (!memcmp(hp, MY_DOMAIN_SUFFIX, domslen)) {
- *hp = '\0';
- }
- }
-
- printf("%s Connection from %s (%s, aka %s). Socket %d\n",
- timestamp,
- inet_ntoa(clientaddress.sin_addr), R->hostname, R->hosttest,
- R->sockfd);
-
- /* This still doesn't do anything.
- *
- * if (hostentp && hostentp->h_name) {
- * memcpy(&R->clienthostent, hostentp, sizeof(struct hostent));
- * for (halias = R->clienthostent.h_aliases; *halias; halias++) {
- * printf(" Host alias:'%s'\n",*halias);
- * }
- * }
- */
-
- R->buffer[0] = '\0';
- bufptr = R->buffer;
-
- /***********************/
- /* NOTE: sometimes, if timing is right, RECV can return a 0 length */
- /* record when a connection is closed by the client!! below is a */
- /* hack to check for a 0 length record, and then terminate this */
- /* connection if we got one. */
- /***********************/
-
- #define RECV_SIZE (sizeof(R->buffer)-1)
-
- for (;;) {
-
- if (is_debug) {
- fprintf(stdout,"recv (sock=%d,size=%d)...\n",R->sockfd,RECV_SIZE);
- fflush(stdout);
- }
-
- if ((len=recv(R->sockfd,outbuf,RECV_SIZE,0)) <= 0) {
- REPORT_TCP_ERROR("RECV - ");
- printf("%s tcp error! len=%d\n",R->hostname, len);
- break;
- }
-
- *(outbuf+(len))=0; /*make sure it's null terminated...*/
- /* printf("len=%d;",len); */
- ASCII_TO_EBCDIC(outbuf,len);
- if (strlen(R->buffer) + strlen(outbuf) >= sizeof(R->buffer)) {
- printf("\nError: More than %d bytes seen without CRLF\n",
- sizeof(R->buffer)-1);
- len = 0;
- break;
- }
- strcat(R->buffer,outbuf);
- bufptr=R->buffer+(strlen(R->buffer)-2);
- if (*bufptr == CARRIAGE_RETURN && *(bufptr+1) == LINE_FEED) break;
- }
-
- /* Note: no \n required, data line already has CRLF in it */
- fprintf(stderr,"%s %s Client data:%s",
- timestamp, R->hostname, R->buffer);
-
- if (len < 0) return;
- else if (len == 0) {
- (void)GGMouts(R,
- "1Sorry, the GOPHER server couldn't hear you. Try again.\t0\t0\t0");
- }
- else (void)GGMproc(R);
-
- (void)GGMouts(R,NULL); /* send terminating dot */
-
- fflush(stdout);
- fflush(stderr);
-
- #ifdef DEBUGMTF
- lookatsocket(R->sockfd);
- #endif
-
- if (is_debug) {
- fprintf(stdout,"close (%d)...\n",R->sockfd);
- fflush(stdout);
- }
-
- if(close(R->sockfd)<0) REPORT_TCP_ERROR("CLOSE - ");
-
- }
- ./ ENDUP
- ?!
- //CLIST EXEC GGLOAD,TRK1='4',TO='CLIST'
- //SYSIN DD DATA,DLM='?!'
- ./ ADD NAME=GOPHER,SSI=010F0028
- /* REXX. GOPHER client. */
-
- /* *** Customize the following lines for your installation.
- * If ggmpanel is set to "", it will not be LIBDEF'd.
- */
-
- ggmprefix = "GOPHER"
- ggmpanelsuffix = "PANELS"
- ggmloadsuffix = "LOAD"
- ggmlmod = "GGCLIENT"
- ggmpanel = ggmprefix"."ggmpanelsuffix
- ggmload = ggmprefix"."ggmloadsuffix
- ggmappl = "" /* ISPF applid (e.g. ISR) */
- ggmdefaulthost = "gopher.micro.umn.edu" /* to initialize GOPHERRC */
- gophermeister = "" /* TSOid of Gopher's Big Brother */
- xprocavailable = 0 /* set to 1 if XPROC is available */
-
- trace off
- signal on novalue
- stacked = 0
- libdeffed = 0
- parse arg args
- "ISPQRY"
- if rc > 0 then do
- parse source . . execname . execds .
- if execds = "?" then
- icmd = "%"execname args
- else
- icmd = "EX '"execds"("execname")'" quote(args)
- call startispf ggmappl, icmd
- exit
- end
-
- if xprocavailable then do
-
- save_prompt = prompt("ON")
- "XPROC 0 TEST DEBUG FORCE LOCAL SERVER() PORT() PATH() DESCRIPTION()"
- if rc <> 0 then exit rc
- call prompt save_prompt
-
- end
-
- else do /* XPROC not available */
-
- server = ""
- port = 70
- path =
- description =
- local =
- force =
- test =
- debug =
- uargs = translate(args)
- if wordpos("LOCAL",uargs) > 0 then local = "LOCAL"
- if wordpos("FORCE",uargs) > 0 then force = "FORCE"
- if wordpos("TEST" ,uargs) > 0 then test = "TEST"
- if wordpos("DEBUG",uargs) > 0 then debug = "DEBUG"
-
- end
-
- signal on failure
- signal on halt
-
- call check_for_other_socket_app
- call read_gopherrc
- call validate_operands
- call libdef
- call let_me_know
- call ggm_dialog
- call unlibdef
-
- cleanup:
- if libdeffed then call unlibdef
- if stacked then "DELSTACK"
- exit
- error:failure:halt:say "GOPHER: Severe lossage."
- say "Statement:" sourceline(sigl)
- exit
-
- /*********************************************************************/
-
- validate_operands:
-
- /*
- * Logic that determines what to display on startup:
- * If gopherrc file does not exist, create it from default
- * (default has everything commented out except for a
- * one-item "initial" menu pointing to the MVS server)
- * Read gopherrc (in case operands need fields therein)
- * Command operands override gopherrc specs:
- * if LOCAL given then server = "-", see below for SERVER(-)
- * if SERVER(host) given then startup host=SERVER, path=PATH, etc.
- * (no gopherrc referenced)
- * if SERVER(-) given then either PATH must be given or
- * the gopherrc's localmenu: must be given,
- * otherwise look at gopherrc
- * if LOCAL given and initial: present then extract startup menu
- * but remember that there will be no server access possible
- * else nothing given, this is an error, barf
- * if no SERVER, look at gopherrc:
- * if initial: given then extract startup menu from there
- * else if localmenu: given then use that menu (SERVER=-)
- * else nothing given, display ISPF panel asking for host/path
- */
-
- if local = "LOCAL" then do
- if server <> "" then do
- say "GOPHER: SERVER cannot be specified when LOCAL is specified."
- exit 12
- end
- server = "-"
- end
-
- ggpath = ""
- gghost = ""
- ggport = port
- ggdesc = description
-
- if server <> "" then do
- if server = "-" then do
- gghost = server
- if path <> "" then do
- ggpath = path
- end
- else if localmenu <> "" then do
- ggpath = localmenu
- if ggdesc = "" then ggdesc = "Local Private Gopher Menu"
- end
- else if local = "LOCAL" & initial <> "" then do
- gghost = ""
- call use_initial_spec
- if gghost <> "-" then do
- say "Gopher: Cannot determine path for local access."
- say " Either specify PATH(pathname), activate"
- say " the localmenu: line in GOPHERRC, or set"
- say " the initial: line in GOPHERRC for local access."
- exit 12
- end
- end
- else do
- say "Gopher: Cannot determine path for local access."
- say " Either specify PATH(pathname) or activate"
- say " the localmenu: or initial: line in GOPHERRC."
- exit 12
- end
- end
- else do
- gghost = server
- ggpath = path
- ggdesc = description
- ggport = port
- nop /* use provided server, host, path, etc. */
- end
- end
- else do /* no server given on command */
- if localmenu <> "" then do
- gghost = "-"
- ggpath = localmenu
- if ggdesc = "" then ggdesc = "Local Private Gopher Menu"
- end
- else if initial <> "" then do
- call use_initial_spec
- end
- else do
- /* this is nominally illegal, but should cause gopher to
- display the hackish startup menu */
- gghost = ""
- ggpath = ""
- end
- end
-
- return
-
- /*********************************************************************/
-
- use_initial_spec:
-
- if initial = "*temp*" then do
- /* we're eventually not going to do it this way really */
- /* initial_type is ignored - only "DIRECTORY" is valid anyway */
- if initial_name <> "" & ggdesc = "" then ggdesc = initial_name
- if initial_host <> "" & gghost = "" then gghost = initial_host
- if initial_path <> "" & ggpath = "" then ggpath = initial_path
- if initial_port <> "" & ggport = "" then ggport = initial_port
- end
- else do
- ggpath = initial
- if ggdesc = "" then ggdesc = "Local Private Gopher Menu"
- end
-
- return
-
- /*********************************************************************/
-
- read_gopherrc:
-
- localmenu = ""
- localexec = ""
- initial = ""
- initial_type = ""
- initial_name = ""
- initial_host = ""
- initial_path = ""
- initial_port = ""
- new_gopherrc = 0
- gopherrc = "'"userid()".GOPHERRC'"
- gopherdcb = "RECFM(V B) LRECL(255) BLKSIZE(6233) DSORG(PS)"
- gopherrc_status = sysdsn(gopherrc)
- select
- when gopherrc_status = "OK" then nop
- when gopherrc_status = "DATASET NOT FOUND" then do
- address TSO "ALLOC DA("gopherrc") T SP(1 1)" gopherdcb
- if rc <> 0 then do
- say "Error: Cannot create" gopherrc
- exit rc
- end
- new_gopherrc = 1
- end
- otherwise do
- say "Error: Cannot access" gopherrc":" gopherrc_status
- exit 16
- end
- end
-
- address TSO "ALLOC FI(GOPHERRC) DA("gopherrc") OLD REU"
- if rc <> 0 then exit rc
-
- if new_gopherrc = 0 then do
- "EXECIO * DISKR GOPHERRC (FINIS STEM GOPHERRC.)"
- execiorc = rc
- if execiorc <> 0 then do
- say "Error: Cannot read" gopherrc
- address TSO "FREE FI(GOPHERRC)"
- exit execiorc
- end
- if gopherrc.0 = 0 then new_gopherrc = 1
- end
-
- if new_gopherrc then call initialize_gopherrc
-
- address TSO "FREE FI(GOPHERRC)"
-
- collecting_initial = 0
- do i = 1 to gopherrc.0
- gline = gopherrc.i
- if gline = "" then iterate
- if left(gline,1) = '#' then iterate
- parse var gline ghead ":" gtext
- ghead = translate(strip(ghead,"B"))
- gtext = strip(gtext,"B")
- if collecting_initial then do
- parse var gline ghead "=" gtext
- ghead = translate(strip(ghead,"B"))
- gtext = strip(gtext,"B")
- select
- when ghead = "TYPE" then initial_type = gtext
- when ghead = "NAME" then initial_name = gtext
- when ghead = "PATH" then initial_path = gtext
- when ghead = "HOST" then initial_host = gtext
- when ghead = "PORT" then initial_port = gtext
- when ghead = "END" then do
- collecting_initial = 0
- initial = "*temp*"
- end
- otherwise do
- say "Error in "gopherrc": INITIAL: not terminated by END"
- say "Line where error was detected:"
- say gline
- exit 8
- end
- end
- end
- else select
- when ghead = "LOCALMENU" then localmenu = gtext
- when ghead = "LOCALEXEC" then localexec = gtext
- when ghead = "INITIAL" then do
- if gtext = "" then collecting_initial = 1
- else initial = gtext
- end
- otherwise do
- say "Warning, gopherrc field ignored:" ghead
- end
- end
- end
-
- return
-
- /*********************************************************************/
-
- ggm_dialog:
-
- vputvars = "GGHOST GGPORT GGPATH GGDESC"
-
- if vputvars <> "" then do
- address ISPEXEC "VPUT ("vputvars") PROFILE"
- if rc <> 0 then do; call ispf_error rc; exit rc; end
- end
-
- parm = ""
- if test = "TEST" then parm = parm "-t"
- if debug = "DEBUG" then parm = parm "-d"
- if local = "LOCAL" then parm = parm "-l"
- if gghost <> "" then parm = parm "-q"
-
- zerrmsg = ""
- zerrsm = ""
- zerrlm = ""
-
- if ggmappl = "" then applsource = ""
- else applsource = "NEWAPPL("ggmappl") PASSLIB"
-
- if ggmload = "" then selstring = "PGM("ggmlmod") PARM("parm")"
- else selstring = "CMD(CALL '"ggmload"("ggmlmod")'" quote(parm)")"
-
- address ISPEXEC "SELECT" applsource selstring
-
- if rc <> 0 then say "Return code from" ggmlmod "program is" rc
-
- address ISPEXEC "VGET (ZERRSM ZERRLM)"
- if zerrsm <> "" then do
- say zerrmsg":" zerrsm
- say zerrlm
- end
-
- return
-
- /*********************************************************************/
-
- libdef:
- if ggmpanel <> "" then do
- address ISPEXEC "LIBDEF ISPPLIB DATASET ID('"ggmpanel"')"
- if rc <> 0 then do; call ispf_error rc; exit rc; end
- end
- if localexec <> "" then do
- address TSO "ALLOC FI(GGEXEC) SHR REU DA('"localexec"')"
- if rc <> 0 then exit rc
- end
- libdeffed = 1
- return
-
- /*********************************************************************/
-
- unlibdef:
- if localexec <> "" then do
- address TSO "FREE FI(GGEXEC)"
- end
- if ggmpanel <> "" then do
- address ISPEXEC "LIBDEF ISPPLIB DATASET"
- if rc <> 0 then call ispf_error rc
- end
- libdeffed = 0
- return
-
- /*********************************************************************/
-
- initialize_gopherrc:
-
- say "Initializing new GOPHERRC file..."
- do i = sigl while sourceline(i) <> "_BEGIN_"
- end
- gx = 0
- do i = i+1 by 1
- gline = sourceline(i)
- if gline = "_END_" then leave
- gpos = pos("ggmdefaulthost",gline)
- if gpos > 0 then do
- gline = substr(gline,1,gpos-1) || ggmdefaulthost
- end
- gx = gx + 1
- gopherrc.gx = gline
- end
- gopherrc.0 = gx
- "EXECIO * DISKW GOPHERRC (FINIS STEM GOPHERRC.)"
- say "New GOPHERRC file initialized."
-
- return
-
- /*
-
- _BEGIN_
- #
- #
- # Default "gopherrc" file, created by the MVS Gopher client.
- #
- # Uncomment desired fields by removing the initial "# " from them.
- #
- # Beware - the Gopher client may update this file with bookmarks.
- # You can delete it at any time and it will be recreated
- # from the default settings, but you'll lose your bookmarks.
- #
- ######################################################################
- #
- # If you want local (serverless) gopher access, then use the following
- # lines, specifying full qualified (no quotes) data set names:
- #
- # localmenu: name_of_initial_gopher_menu
- # localexec: name_of_pds_of_rexx_execs
- #
- # Specifying localmenu: is equivalent to specifying an initial: section
- # with host set to "-" and path set to the value of localmenu.
- #
- # You cannot use your own REXX execs, however, unless you specify
- # localexec: as above. You don't need one to use the other, though.
- #
- ######################################################################
- #
- # The following is used by the Gopher client at startup to determine
- # how the initial menu will appear.
- #
- # You may want to change the host to the one appropriate for your site.
- #
- initial:
- #
- Type=DIRECTORY
- Name=Primary (Root) Gopher Menu
- Path=
- Host=ggmdefaulthost
- Port=70
- End
- #
- # Alternatively, if you want your own private Gopher data:
- #
- # initial:
- #
- # Type=0
- # Name=My Own Private Gopherhole
- # Path=userid.GOPHER.MENU
- # Host=-
- # End
- #
- # In which case you should create a data set called userid.GOPHER.MENU
- # (or whatever name you choose that appears in the "Path=" line above)
- # that looks like this. (NOT in the gopherrc file!)
- #
- #
- # gopher_menu
- #
- # TYPE=DIRECTORY
- # NAME=Public GOPHER Server at ggmdefaulthost
- # PATH=
- # HOST=ggmdefaulthost
- # END
- #
- # TYPE=DIRECTORY
- # NAME=Private GOPHER
- # PATH=userid.ANOTHER.GOPHER.MENU
- # HOST=-
- # END
- #
- # and then you need yet another menu, similar in format to this one,
- # in userid.ANOTHER.GOPHER.MENU. Get the idea?
- #
- ######################################################################
- #
- # These fields may be used by the Gopher client for local purposes
- # in the future. Currently they are ignored.
- #
- # Printercmd: lpr
- # Telnetcmd: telnet
- # Mailcmd: mail
- # Playcmd: play -v 40 -
- # TN3270cmd: tn3270
- # MIMEcmd: metamail -p
- #
- ######################################################################
- _END_
-
- */
-
- /*********************************************************************/
-
- check_for_other_socket_app:
-
- if local = "LOCAL" then return
-
- call nnmfiucv /* FIND IUCVMULT in another PIE MultiTSO session */
-
- if result = 0 then return
-
- say,
- "A TCP/IP socket application appears active in another PIE session."
- if force = "FORCE" then do
- say "Proceeding anyhow, because you said FORCE."
- return
- end
- say "To proceed at this point would be potentially disastrous."
- say "If you want to use GOPHER anyway, use one of these operands:"
- say " FORCE - if I'm mistaken and it's really safe to make a"
- say " TCP/IP connection."
- say " LOCAL - if you just want local (serverless) access."
- say "Terminating."
-
- exit 16
-
- /*********************************************************************/
-
- ispf_error: parse arg ispfrc
-
- say "GOPHER: ISPF dialog service error detected on line" sigl
- say sourceline(sigl)
- say
- say zerrmsg":" zerrsm
- say zerrlm
- say
-
- return ispfrc
-
- /*********************************************************************/
-
- /*
- * The following function starts ISPF from READY mode.
- * Beware: splitting the screen starts up an identical copy of the
- * application, which may not be desirable.
- */
-
- startispf: parse arg startappl, startcmd
- if startappl = "" then,
- "ISPSTART CMD("startcmd")"
- else,
- "ISPSTART NEWAPPL("startappl") CMD("startcmd")"
- return
-
- /* The following function implements Big Brother mode. */
-
- let_me_know:
- if gophermeister = "" | gophermeister = userid() then return
- parse source . . execname . execds .
- call outtrap "X."
- address TSO,
- "SEND" quote(execds"("execname")" date("U") time()" "),
- "U("gophermeister") LOGON"
- call outtrap "OFF"
- return
-
- /* The following function enquotes a string. */
-
- quote: parse arg string
- ix = 1
- do forever
- ix = pos("'",string,ix)
- if ix = 0 then return "'"string"'"
- string = insert("'",string,ix)
- ix=ix+2
- end
-
- ./ ADD NAME=NNMFIUCV,SSI=01000017
- /* REXX. This exec scans the job pack queues for IUCVMULT and returns
- * with an error code if IUCVMULT is already loaded under a
- * different TCB. This can only happen under PIE MultiTSO or a
- * similar product that makes multiple job step TCB's.
- */
-
- trace off
- signal on novalue
-
- search_name = "IUCVMULT"
- count = 0
- foundtcb. = ""
- current_tcb = getword24("21C")
- current_job_step_tcb = getword24(current_tcb,"7C")
- current_ascb = getword24("224")
- current_asxb = getword31(current_ascb,"6C")
- first_tcb = getword24(current_asxb,"4")
- tcb = first_tcb
- motherflag = 0
- do forever
- if motherflag = 0 then do
- call process
- daughter_tcb = getword24(tcb,"88")
- if daughter_tcb \= "00000000" then do
- tcb = daughter_tcb
- iterate
- end
- end
- motherflag = 0
- sister_tcb = getword24(tcb, "80")
- if sister_tcb \= "00000000" then do
- tcb = sister_tcb
- iterate
- end
- mother_tcb = getword24(tcb, "84")
- if mother_tcb \= "00000000" then do
- tcb = mother_tcb
- motherflag = 1
- iterate
- end
- leave
- end
-
- if count = 0 then return 0
- problem = 0
- do i = 1 to count
- if foundtcb.i = current_job_step_tcb then do
- /*
- say search_name "is already loaded under current TCB at "foundtcb.i"."
- */
- end
- else do
- /*
- say search_name "is loaded under different TCB at "foundtcb.i"."
- */
- problem = 1
- end
- end
-
- if problem = 1 then return 1
-
- else return 0
-
- process:
-
- jpq = getword31(tcb,"2C")
- cde = jpq
- do while cde \= "00000000"
- cde_contents = storage(cde,32)
- cde_name = substr(cde_contents,9,8)
- cde_epa = substr(cde_contents,9,8)
- if search_name = cde_name then do
- count = count + 1
- foundtcb.count = tcb
- end
- cde = getword31(cde,"0")
- end
-
- return
-
- getword31: parse arg addr, offset
- temp1 = x2d(addr)
- if offset = "" then temp2 = 0
- else temp2 = x2d(offset)
- return c2x(storage(d2x(temp1+temp2),4))
-
- getword24: parse arg addr, offset
- temp1 = x2d(addr)
- if offset = "" then temp2 = 0
- else temp2 = x2d(offset)
- return "00"c2x(storage(d2x(temp1+temp2+1),3))
-
- ./ ENDUP
- ?!
- //H EXEC GGLOAD,TRK1='4',TO='H'
- //SYSIN DD DATA,DLM='?!'
- ./ ADD NAME=GG,SSI=013F0021
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- /* --------------------- "gg.h" include member --------------------- */
-
- #pragma linkage(GGMbrifr,FORTRAN)
- #pragma linkage(GGMbrifc,FORTRAN)
- #pragma linkage(ispexec,OS)
- #pragma linkage(isplink,OS)
- #pragma linkage(ikjeff18,OS)
-
- /****** Installation-customized defines. *****************************/
-
- #include "gguser.h"
-
- #ifndef C370V1
- #ifndef C370V2
- #ifndef SASC
- install_error_neither_C370V1_C370V2_nor_SASC_was_defined;
- #endif
- #endif
- #endif
-
- #ifndef TCPIPV1
- #ifndef TCPIPV2
- #ifndef SNSTCPIP
- install_error_neither_TCPIPV1_TCPIPV2_nor_SNSTCPIP_was_defined;
- #endif
- #endif
- #endif
-
- #define MVS
-
- /****** Clean up compiler warnings BEFORE time.h gets 'em ************/
-
- #ifndef SASC
- #define localtime LOCALTIM
- #endif
-
- /****** Include all header files that are necessary. *****************/
-
- #ifndef SNSTCPIP
- #include <manifest.h>
- #include <sys/types.h>
- #include <netinet/in.h>
- #include <sys/ioctl.h>
- #include <tcperrno.h>
- #include <fcntl.h>
- #endif
-
- #include <sys/socket.h>
- #include <netdb.h>
- #include <sys/uio.h>
- #include <ctype.h>
- #include <errno.h>
- #include <limits.h>
- #include <setjmp.h>
- #include <stdio.h>
- #include <stdarg.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stddef.h>
- #include <time.h>
-
- #ifdef SNSTCPIP
- #include <acs.h>
- #include <inet.h>
- #include <sockcfg.h>
- #include <serrno.h>
- #endif
-
- #ifndef SASC
- #include <ctest.h>
- #endif
-
- #ifdef SASC
- #include "ggsasc.h"
- #endif
-
- #undef ENOMEM
-
- #include <mtf.h>
-
- /****** Version-dependent stuff **************************************/
-
- #ifdef C370V1
- #undef FETCH
- #endif
-
- #ifdef C370V2
- #define FETCH
- #endif
-
- #ifdef TCPIPV1
- #define TCP_DEBUG tcp_debug
- #endif
-
- #ifdef TCPIPV2
- #define TCP_DEBUG sock_debug
- #endif
-
- #ifdef SNSTCPIP
- #define TCP_DEBUG /* I don't know how to debug in SNS */
- #undef DEBUG
- #endif
-
- #ifdef DEBUG
- #define TCP_DEBUG_ON TCP_DEBUG(1)
- #define TCP_DEBUG_OFF TCP_DEBUG(0)
- #else
- #define TCP_DEBUG_ON /* */
- #define TCP_DEBUG_OFF /* */
- #endif
-
- /****** Preprocessor bookkeeping *************************************/
-
- #define Bool char
- #define Fool unsigned int /* for function arguments */
- #ifndef TRUE
- #define TRUE 1
- #endif
- #ifndef FALSE
- #define FALSE 0
- #endif
-
- #define COMMANDSIZE 12
-
- #define GOPHER_FILE '0'
- #define GOPHER_DIRECTORY '1'
- #define GOPHER_CSO '2'
- #define GOPHER_ERROR '3'
- #define GOPHER_MAC_BINHEX '4'
- #define GOPHER_DOS_BINARCH '5'
- #define GOPHER_UUENCODE '6'
- #define GOPHER_WAIS '7'
- #define GOPHER_TELNET '8'
- #define GOPHER_TN3270 'T'
- #define GOPHER_BINARY '9'
- #define GOPHER_REDUNDANT '+'
- #define GOPHER_WHOIS 'w'
-
- #define READ_BYTES 1024
- #define SERVER_BUF_MSGSIZE 1024
- #define CLIENT_BUF_MSGSIZE 1024
- #define TEXT_BYTES 1024
- #define INTERNET_SIZE 256
- #define RBUFSIZE 256
- #define OUTBUFSIZE 1024
-
- #define GOPHER_PORT_NUMBER 70
- #define GOPHER_HOST_LENGTH MAXHOSTNAMELEN
- #define GOPHER_PATH_LENGTH 512
- #define GOPHER_DESC_LENGTH 256
-
- #define SOCKET_GETCHAR_ERROR (-1)
- #define SOCKET_NO_MORE (-2)
- #define SOCKET_READ_NOTHING (-3)
-
- #define NO_VALUE (-1)
-
- #define Rstruc register struct
-
- #define EQUAL !strcmp
- #define UNEQUAL strcmp
-
- #define CARRIAGE_RETURN ('\r')
-
- #ifdef MVS
- #ifdef I370
- #define LINE_FEED (0x15)
- #else
- #define LINE_FEED (0x25)
- #endif
- #else
- #define LINE_FEED (0x0a)
- #endif
-
- #ifdef MVS
- #ifdef SNSTCPIP
- #define EtoA etoa
- #define AtoE atoe
- #else
- #ifdef I370
- #define EtoA htoncs
- #define AtoE ntohcs
- #else
- #define EtoA(x) ebcdictoascii[x]
- #define AtoE(x) asciitoebcdic[x]
- #define ebcdictoascii ebcdicto
- #define asciitoebcdic asciitoe
- #endif
- #endif
- #endif
-
- #ifdef SNSTCPIP
- #define EBCDIC_TO_ASCII(A,B) EtoA(A,B)
- #define ASCII_TO_EBCDIC(A,B) AtoE(A,B)
- #else
- #define EBCDIC_TO_ASCII(A,B) {int _i; \
- for (_i=0; _i<(B); ++_i) \
- (A)[_i] = EtoA((A)[_i]); \
- }
- #define ASCII_TO_EBCDIC(A,B) {int _i; \
- for (_i=0; _i<(B); ++_i) \
- (A)[_i] = AtoE((A)[_i]); \
- }
- #endif
-
- #ifdef TCPIPV1
- #define REPORT_TCP_ERROR(A) /* */
- #endif
-
- #ifdef TCPIPV2
- #define REPORT_TCP_ERROR(A) tcperror(A)
- #endif
-
- #ifdef SNSTCPIP
- #define REPORT_TCP_ERROR(A) fprintf(stderr,\
- "\nTCP error on %s: errno = %d\n",\
- A,GET_ERRNO)
- #endif
-
- #ifdef SNSTCPIP
- #define Accept(A,B,C) accept((A),(struct sockaddr *)(B),(C))
- #define Bind(A,B,C) bind((A),(struct sockaddr *)(B),(C))
- #define Connect(A,B,C) connect((A),(struct sockaddr *)(B),(C))
- #define Gethostbyaddr(A,B,C) gethostbyaddr((char *)(A),(B),(C))
- #define Getpeername(A,B,C) getpeername((A),(struct sockaddr *)(B),(C))
- #define Getsockopt(A,B,C,D,E) getsockopt((A),(B),(C),(char *)(D),(E))
- #define EWOULDBLOCK (ESWOULDBLOCK+s0skcfg.errnobase)
- #else
- #define Accept accept
- #define Bind bind
- #define Connect connect
- #define Gethostbyaddr gethostbyaddr
- #define Getpeername getpeername
- #define Getsockopt getsockopt
- #endif
-
- #ifdef FETCH
- #define ISPLINK (gp->isplink_pointer)
- #define ISPEXEC (gp->ispexec_pointer)
- #else
- #define ISPLINK isplink
- #define ISPEXEC ispexec
- #endif
-
- #define DATAOUT_LOW 0x01
- #define DATAOUT_HIGH 0x02
- #define DATAIN_LOW 0x03
- #define DATAIN_HIGH 0x04
- #define DATAOUT_BLUE DATAOUT_LOW
- #define DATAOUT_GREEN 0x05
- #define DATAOUT_PINK 0x06
- #define DATAOUT_RED 0x07
- #define DATAOUT_TURQ 0x08
- #define DATAOUT_WHITE DATAOUT_HIGH
- #define DATAOUT_YELLOW 0x09
- #define DATAIN_BLUE 0x0a
- #define DATAIN_GREEN DATAIN_LOW
- #define DATAIN_PINK 0x0b
- #define DATAIN_RED DATAIN_HIGH
- #define DATAIN_TURQ 0x0c
- #define DATAIN_WHITE 0x0d
- #define DATAIN_YELLOW 0x0e
-
- #define S99VRBAL 0x01 /* ALLOCATION */
- #define S99VRBUN 0x02 /* UNALLOCATION */
- #define S99VRBCC 0x03 /* CONCATENATION */
- #define S99VRBDC 0x04 /* DECONCATENATION */
- #define S99VRBRI 0x05 /* REMOVE IN-USE */
- #define S99VRBDN 0x06 /* DDNAME ALLOCATION */
- #define S99VRBIN 0x07 /* INFORMATION RETRIEVAL */
- #define S99NOCNV 0x40 /* ALLOC FUNCTION-DO NOT USE AN */
- /* EXISTING ALLOCATION TO SATISFY*/
- /* THE REQUEST */
- #define DALDDNAM 0x0001 /* DDNAME */
- #define DALDSNAM 0x0002 /* DSNAME */
- #define DALMEMBR 0x0003 /* MEMBER NAME */
- #define DALSTATS 0x0004 /* DATA SET STATUS */
- #define DALNDISP 0x0005 /* DATA SET DISPOSITION */
- #define DALBLKLN 0x0009 /* BLOCK LENGTH */
- #define DALPRIME 0x000a /* PRIMARY SPACE ALLOCATION */
- #define DALSECND 0x000b /* SECONDARY SPACE ALLOCATION */
- #define DALDIR 0x000c /* DIRECTORY BLOCK ALLOCATION */
- #define DALBLKSZ 0x0030 /* DCB BLOCKSIZE */
- #define DALDSORG 0x003c /* DATA SET ORGANIZATION */
- #define DALLRECL 0x0042 /* DCB LOGICAL RECORD LENGTH */
- #define DALRECFM 0x0049 /* DCB RECORD FORMAT */
- #define DALPERMA 0x0052 /* PERMANENTLY ALLOCATED ATTRIB */
- #define DALRTDDN 0x0055 /* RETURN DDNAME */
- #define DALRTDSN 0x0056 /* RETURN DSNAME */
- #define DALRTORG 0x0057 /* RETURN D.S. ORGANIZATION */
- #define DUNDDNAM 0x0001 /* DDNAME */
- #define DUNDSNAM 0x0002 /* DSNAME */
- #define DUNUNALC 0x0007 /* UNALLOC OPTION */
-
- #define SHR 0x08
- #define NEW 0x04
- #define MOD 0x02
- #define OLD 0x01
- #define KEEP 0x08
- #define DELETE 0x04
- #define CATLG 0x02
- #define UNCATLG 0x01
- #define RECFM_F 0x80
- #define RECFM_V 0x40
- #define RECFM_U 0xc0
- #define RECFM_D 0x20
- #define RECFM_T 0x20
- #define RECFM_B 0x10
- #define RECFM_S 0x08
- #define RECFM_A 0x04
- #define RECFM_M 0x02
- #define RECFM_FB (RECFM_F | RECFM_B)
- #define RECFM_VB (RECFM_V | RECFM_B)
- #define DSORG_PS 0x4000
- #define DSORG_PO 0x0200
-
-
- /****** Data and structure definitions. ******************************/
-
- typedef struct _textunit TEXTUNIT;
- typedef unsigned int IPADDRESS;
- typedef char gophertype;
-
- enum socket_retval {
- SERVER_READ_OK,
- SERVER_READ_ERROR,
- SERVER_BUFFER_ERROR,
- SERVER_NO_MORE,
- SERVER_READ_NOTHING
- };
-
- enum data_set_type {
- PDS,
- SEQ,
- UNK
- };
-
- enum user_option {
- OPTION_ALL,
- OPTION_VIEW,
- OPTION_OTHER
- };
-
- struct textline {
- struct textline *next;
- short text_length;
- short tab_expanded_text_length;
- char *tab_expanded_text;
- char text[1]; /* dummy */
- };
-
- struct texthdr {
- int text_line_count;
- struct textline *text_body_line;
- short text_max_length;
- short text_max_tab_expanded_length;
- struct textline *first_text_line;
- struct textline *current_text_line;
- struct textline *last_text_line;
- };
-
- struct cmddesc {
- char command_name[COMMANDSIZE];
- Bool (*command_processor)();
- };
-
- struct seldesc {
- char selection_code;
- Bool (*selection_processor)();
- };
-
- struct tabledesc {
- char *command_variable;
- struct cmddesc *first_cmddesc;
- struct seldesc *first_seldesc;
- };
-
- struct _textunit {
- unsigned short key;
- unsigned short num;
- struct {
- unsigned short len;
- char prm[80];
- } ent;
- };
-
- struct extraction {
- int from_number;
- int to_number;
- int count;
- enum data_set_type mode;
- Bool appending;
- Bool blanking;
- Bool tab_expanding;
- char panelname [9];
- char dsname [65];
- char separator [81];
- char member_prefix [9];
- char ddname [9];
- };
-
- struct gopherinfo {
- gophertype type;
- int port;
- struct texthdr thdr;
- char path [GOPHER_PATH_LENGTH+1];
- char host [GOPHER_HOST_LENGTH+1];
- char desc [GOPHER_DESC_LENGTH+1];
- };
-
- struct recvstruct {
- int sockfd; /* socket descriptor for socket call */
- int outlen;
- FILE *outfp; /* used by local (non-socket) interface*/
- char *fileptr;
- char *wargptr;
- FILE *readfile; /* declare the file... */
- struct hostent clienthostent;
- char myname [MAXHOSTNAMELEN+1];
- char hostname[MAXHOSTNAMELEN+1]; /* client host name */
- char hosttest[MAXHOSTNAMELEN+1]; /* client host name */
- char buffer [RBUFSIZE]; /* client's character string */
- char dsname [RBUFSIZE];
- char sockbuf [OUTBUFSIZE]; /* socket output buffer */
- };
-
- struct menuitem {
- char type; /* type of record to send */
- char desc [GOPHER_DESC_LENGTH+1];
- char select [GOPHER_PATH_LENGTH+1];
- char hostname [GOPHER_HOST_LENGTH+1];
- int port; /* host port to connect to */
- };
-
- struct ggcb {
- char *server_buf;
- char *client_buf;
- char *gopher_command;
- struct recvstruct *recvp;
- char *extract_separator_line;
- #ifdef FETCH
- int (*isplink_pointer)();
- int (*ispexec_pointer)();
- #endif
- int ispfrc;
- int socknum;
- int g_bytes_returned;
- int g_buf_index;
- int brif_previous_recno;
- FILE *debug_file;
- FILE *extract_file;
- struct texthdr *brifp;
- struct texthdr thdr;
- struct gopherinfo *ginfo;
- Bool test_mode;
- Bool debug_mode;
- Bool quit;
- Bool time_to_go_home;
- Bool server_has_something_pending;
- Bool server_finished_replying;
- Bool sending_text;
- Bool receiving_text;
- Bool local_mode;
- Bool dont_read;
- Bool connected_to_server;
- Bool connection_broken;
- Bool closing_connection;
- Bool reconnect_in_progress;
- Bool extract_tab_expanding;
- Bool extract_appending;
- Bool extract_blank_before_separator;
- Bool extract_write_error;
- Bool extract_close_error;
- Bool warn_overwrite;
- Bool warn_append;
- Bool setmsg;
- Bool autoscroll;
- IPADDRESS client_ip_address;
- IPADDRESS server_ip_address;
- char ggserver [MAXHOSTNAMELEN+1];
- char ggclient [MAXHOSTNAMELEN+1];
- char client_hostname [MAXHOSTNAMELEN+1];
- char client_ip_addrstr [16];
- char server_hostname [MAXHOSTNAMELEN+1];
- char server_ip_addrstr [16];
- char g_buf [READ_BYTES];
- };
-
- #ifdef MVS
- #ifndef I370
- extern char ebcdictoascii[];
- extern char asciitoebcdic[];
- #endif
- #endif
-
- #ifndef FETCH
- extern int isplink();
- extern int ispexec();
- #endif
-
- #define NOTIFY_MSG 1
- #define WARNING_MSG 2
- #define CRITICAL_MSG 3
-
- #define WARN1(X) GGMpmsg(gp,NOTIFY_MSG,NULL,X)
- #define WARN2(X,Y) GGMpmsg(gp,NOTIFY_MSG,NULL,X,Y)
- #define WARN3(X,Y,Z) GGMpmsg(gp,NOTIFY_MSG,NULL,X,Y,Z)
- #define WARN4(X,Y,Z,W) GGMpmsg(gp,NOTIFY_MSG,NULL,X,Y,Z,W)
- #define ERR1(X) GGMpmsg(gp,WARNING_MSG,NULL,X)
- #define ERR2(X,Y) GGMpmsg(gp,WARNING_MSG,NULL,X,Y)
- #define ERR3(X,Y,Z) GGMpmsg(gp,WARNING_MSG,NULL,X,Y,Z)
- #define ERR4(X,Y,Z,W) GGMpmsg(gp,WARNING_MSG,NULL,X,Y,Z,W)
- #define CRIT1(X) GGMpmsg(gp,CRITICAL_MSG,NULL,X)
- #define CRIT2(X,Y) GGMpmsg(gp,CRITICAL_MSG,NULL,X,Y)
- #define CRIT3(X,Y,Z) GGMpmsg(gp,CRITICAL_MSG,NULL,X,Y,Z)
-
- #define GETMAIN(Ptr,Typ,Siz,For) \
- GGMgetm(gp,(char **)&(Ptr),(sizeof(Typ))*(Siz),For)
-
- #define FREEMAIN(Ptr,For) if (Ptr) {GGMfreem(gp,(char *)Ptr,For);}
-
- #ifndef I370
-
- #define OPEN_TEXT_FILE_FOR_WRITE(F) \
- fopen((F),"w,recfm=vb,lrecl=259,blksize=6233")
-
- #define OPEN_TEXT_FILE_FOR_APPEND(F) \
- fopen((F),"a,recfm=vb,lrecl=259,blksize=6233")
-
- #define OPEN_TEXT_FILE_FOR_WRITE_OR_APPEND(F,B) \
- fopen((F),(B) ? "a,recfm=vb,lrecl=259,blksize=6233" \
- : "w,recfm=vb,lrecl=259,blksize=6233")
-
- #else
-
- #define OPEN_TEXT_FILE_FOR_WRITE(F) \
- afopen((F),"w","seq","recfm=v,lrecl=255,blksize=6233")
-
- #define OPEN_TEXT_FILE_FOR_APPEND(F) \
- afopen((F),"a","seq","recfm=v,lrecl=255,blksize=6233")
-
- #define OPEN_TEXT_FILE_FOR_WRITE_OR_APPEND(F,B) \
- afopen((F),(B)?"a":"w","seq","recfm=v,lrecl=255,blksize=6233")
-
- #endif
-
- #define ebdtoasc(C) {char *__cp;\
- for(__cp = C;*__cp;__cp++) *__cp = EtoA(*__cp);}
-
- #define asctoebd(C) {char *__cp;\
- for(__cp = C;*__cp;__cp++) *__cp = AtoE(*__cp);}
-
- #define uppercase_in_place(C) {char *__cp;\
- for(__cp=C;*__cp;__cp++) *__cp = toupper(*__cp);}
-
- #define lowercase_in_place(C) {char *__cp;\
- for(__cp=C;*__cp;__cp++) *__cp = tolower(*__cp);}
-
-
- /****** Procedure and function declarations. *************************/
-
- extern enum data_set_type GGMalloc(char *, char *, enum data_set_type,
- int);
- extern int GGMbrifr(char **, int *, int *, void *);
- extern int GGMbrifc(int *, void *);
- extern void GGMbtext(struct ggcb *, struct texthdr *,
- FILE *);
- extern void GGMclrtx(struct ggcb *,struct gopherinfo *);
- extern Bool GGMconn (struct ggcb *);
- extern char *GGMcopy (struct ggcb *, char *);
- extern Bool GGMcso (struct ggcb *,struct gopherinfo *,
- Fool);
- extern void GGMdfail(int,__S99parms *);
- extern Bool GGMdir (struct ggcb *,struct gopherinfo *,
- Fool);
- extern void GGMdisc (struct ggcb *);
- extern int GGMdispl(struct ggcb *, char *);
- extern void GGMdump (struct ggcb *,char *, char *, int);
- extern void GGMesrvr(struct ggcb *);
- extern void GGMfreem(struct ggcb *,char *,char *);
- extern FILE *GGMgetds(struct ggcb *,struct extraction *);
- extern void GGMgetm (struct ggcb *,char **,int,char *);
- extern Bool GGMgofor(struct ggcb *,struct gopherinfo *,
- Fool);
- extern Bool GGMgsrvl(struct ggcb *, char **, Fool);
- extern void GGMierr (struct ggcb *);
- extern int GGMiget (struct ggcb *, char *);
- extern void GGMimsg (struct ggcb *, char *);
- extern Bool GGMispf (struct ggcb *, char *);
- extern Bool GGMivget(struct ggcb *, char *, char *,int);
- extern Bool GGMivput(struct ggcb *, char *, char *,int);
- extern void GGMmtfer(int, char*);
- extern struct textline *GGMouttx(struct ggcb *, char *,
- struct gopherinfo *);
- extern Bool GGMouts (struct recvstruct *, char *);
- extern Bool GGMproc (struct recvstruct *);
- extern void GGMrbfm (struct ggcb *);
- extern void GGMrperr(struct ggcb *);
- extern Bool GGMsockt(struct ggcb *);
- extern void GGMsopt (struct ggcb *,enum user_option);
- extern char *GGMstrlc(char *, char *);
- extern Bool GGMtnet (struct ggcb *,struct gopherinfo *,
- Fool);
- extern int GGMtso (char *);
- extern char *GGMtype (gophertype);
- extern Bool GGMunalc(char *);
- extern Bool GGMvtx (struct ggcb *,struct gopherinfo *,
- Fool);
- extern Bool GGMwais (struct ggcb *,struct gopherinfo *,
- Fool);
- extern Bool GGMwhois(struct ggcb *,struct gopherinfo *,
- Fool);
- extern Bool GGMxlist(struct ggcb *,char *);
- extern Bool GGMxtx (struct ggcb *,struct gopherinfo *);
-
- #ifndef SUPPRESS_V_DECLARATION
- extern void GGMpmsg (struct ggcb *,int,char *,char *,
- ...);
- #endif
-
- ./ ADD NAME=GGSASC,SSI=01000043
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* SAS modifications due to Dale Ingold at SAS Institute, Inc. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- /* ------------------- "ggsasc.h" include member ------------------- */
-
- #ifdef SASC
-
- #define I370
-
- #include <dynam.h>
-
- #define FETCH
-
- __inline void (*fetch( const char *modname ))()
- {
- void (*fpp)();
-
- loadm( modname, &fpp );
- return( fpp );
- }
-
- __inline int (*release( void (*fpp)() ))
- {
- unloadm( fpp );
- return( 0 );
- }
-
-
- #ifndef __SVC99
-
- #define __SVC99 1
-
- #include <code.h>
-
- struct __S99struc
- {
- unsigned char __S99RBLN; /* length of request block..20 */
- unsigned char __S99VERB; /* verb code */
- unsigned short __S99FLAG1; /* FLAGS1 field of SVC99 Req Block */
- unsigned short __S99ERROR; /* error code field */
- unsigned short __S99INFO; /* information reason code */
- void *__S99TXTPP; /* address of text unit pointer list*/
- int __reserved; /* reserved..will always be 0 */
- unsigned int __S99FLAG2; /* FLAGS2 field..can only be filled */
- /* in by APF authorized programs */
- };
-
- typedef struct __S99struc __S99parms;
-
- __inline int svc99(__S99parms* svc99parmlist)
- { return( (_ldregs(R1, &svc99parmlist),
- _code(0, 0x0a63),
- _stregs(R15) ) );
- }
-
- #endif
-
- #define FALSE 0
- #define TRUE 1
-
- #include <lcio.h>
-
- #define MAXHOSTNAMELEN 64
-
- #define __ctest(X) fprintf(stderr,\
- "GGMVS: CTEST is not supported by this compiler.")
-
- #endif
-
- ./ ADD NAME=GGUSER,SSI=01180036
-
- /********************************************************************/
- /* */
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 */
- /* */
- /* GOPHER server due to Shawn Hart at the University of Delaware. */
- /* */
- /* This software is provided on an "AS IS" basis. All warranties, */
- /* including the implied warranties of merchantability and fitness, */
- /* are expressly denied. */
- /* */
- /* Provided this copyright notice is included, this software may */
- /* be freely distributed and not offered for sale. */
- /* */
- /* Changes or modifications may be made and used only by the maker */
- /* of same, and not further distributed. Such modifications should */
- /* be mailed to the author for consideration for addition to the */
- /* software and incorporation in subsequent releases. */
- /* */
- /********************************************************************/
-
- /* ------------------- "gguser.h" include member ------------------- */
-
- /* Include file for locally customized values. */
-
- /* Define levels of C/370 and TCP/IP. This controls support for
- * fetching of non-C load modules and socket error reporting.
- */
-
- /* #define C370V1 /* define this if C/370 Version 1 */
- #define C370V2 /* define this if C/370 Version 2 or higher */
- /* #define SASC /* define this if SAS/C compiler */
-
- /* #define TCPIPV1 /* define this if TCP/IP Version 1 */
- #define TCPIPV2 /* define this if TCP/IP Version 2 or higher */
- /* #define SNSTCPIP /* define this if SNS/TCPAccess */
-
- /* Define the following defaults for your installation. */
- /* Use XTELNET if you like the CSOCK package from UCLA. */
-
- #define TELNET_COMMAND_NAME "TELNET"
- /* #define TELNET_COMMAND_NAME "XTELNET" */
-
- /* Define this if the server host name set by the "+" frob
- * should have the domain name appended. Note that this will
- * affect how the hostname needs to be specified for a
- * Path=(pdsmember) specification - it must match the local host
- * the way it is generated here. Of course, host=+ will do it anyway.
- */
-
- #define APPEND_DOMAIN_NAME_TO_SELF
- /* #undef APPEND_DOMAIN_NAME_TO_SELF */
-
- /*
- * Turn on for TCP-level debugging output (you probably don't want to
- * unless your TCP/IP stuff is really broken and I can't help you).
- */
-
- /* #define DEBUG */
- #undef DEBUG
-
- /*
- * Turn on for MTF-level debugging output.
- */
-
- /* #define DEBUGMTF */
- #undef DEBUGMTF
-
- /* Server and MTF stuff. */
-
- /* #define MTF_TASKS 8 */
- #define MTF_TASKS 1 /* lest REXX multitasking lossage */
- #define TCP_QUEUE_LENGTH 20
- #define SERV_TCP_PORT 70
- #define CONNECT_TIME_OUT 60
- #define DEFAULT_DIRECTORY "DD:GGGOPHER"
- #define ACCESS_TABLE "DD:GGACCESS"
- #define MY_DOMAIN_SUFFIX ".DRAPER.COM"
-
- /* note: could get MY_DOMAIN_SUFFIX from TCPIP startup - what call? */
-
- /* Client stuff. */
-
- #define INITIAL_TYPE GOPHER_DIRECTORY
- #define INITIAL_PORT GOPHER_PORT_NUMBER
- #define INITIAL_PATH ""
- #define INITIAL_HOST "MVS.DRAPER.COM"
- #define INITIAL_DESC "Root"
-
- /* Server and client stuff. */
-
- #define IDENT_HOST_FROB "+"
- #define LOCAL_HOST_FROB "-"
-
- /********************************************************************/
- /* The following defines the module name for the MTF subtask. */
- /********************************************************************/
-
- #define GOPHER_PARALLEL_TASK "GGSTASK"
-
- /********************************************************************/
- /* following are "gopher" record types. */
- /********************************************************************/
-
- #define GFILE '0'
- #define MENU '1'
- #define ERROR '2'
- #define INDEX '7'
- #define TELNET '8'
- #define TN3270 'T'
- #define WHOIS 'w'
-
- /********************************************************************/
- /* following are MVS file type identifiers. They must appear at the
- beginning of the file they're identifying. */
- /********************************************************************/
-
- #define MENUIDENT "GOPHER_MENU"
- #define INDEXIDENT "GOPHER_INDEX"
-
- /********************************************************************/
- /* following are tokens for menu GOPHER identifiers. */
- /********************************************************************/
-
- #define TOKTYPE "TYPE"
- #define TYPETOK 0
- #define TOKNAME "NAME"
- #define NAMETOK 1
- #define TOKPATH "PATH"
- #define PATHTOK 2
- #define TOKHOST "HOST"
- #define HOSTTOK 3
- #define TOKPORT "PORT"
- #define PORTTOK 4
- #define TOKEND "END"
- #define ENDTOK 5
- #define TOKCOMMENT "*"
- #define COMMENTTOK 6
-
- #define TOKDISPLAY "DISPLAY"
- #define DISPLAYTOK 7
- #define TOKSELECT "SELECTOR"
- #define SELECTTOK 8
-
- /********************************************************************/
- /* types of "types" - operands of the TYPE keyword in directories.*/
- /********************************************************************/
-
- #define TYPEFILE "FILE"
- #define TYPEMENU "DIRECTORY"
- #define TYPEINDEX "INDEX"
- #define TYPETELNET "TELNET"
- #define TYPETN3270 "TN3270"
- #define TYPEWHOIS "WHOIS"
-
- /********************************************************************/
- /* used by the REXX Interface */
- /********************************************************************/
-
- /* Be sure to include all 8 bytes, including blanks, in below */
-
- #define REXX_EXEC_LIBRARY_DDNAME "GGEXEC "
- #define REXX_EXEC_SUBCOM " "
-
- ./ ENDUP
- ?!
- //PANELS EXEC GGLOAD,TRK1='4',TO='PANELS'
- //SYSIN DD DATA,DLM='?!'
- ./ ADD NAME=GGM,SSI=01060053
- )ATTR
- /* /*
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 /*
- /* /*
- /* This software is provided on an "AS IS" basis. All warranties, /*
- /* including the implied warranties of merchantability and fitness, /*
- /* are expressly denied. /*
- /* /*
- /* Provided this copyright notice is included, this software may /*
- /* be freely distributed and not offered for sale. /*
- /* /*
- /* Changes or modifications may be made and used only by the maker /*
- /* of same, and not further distributed. Such modifications should /*
- /* be mailed to the author for consideration for addition to the /*
- /* software and incorporation in subsequent releases. /*
- /* /*
- ^ TYPE(INPUT) INTENS(HIGH) COLOR(GREEN) CAPS(OFF)
- ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)
- )BODY EXPAND(``)
- %-`-`- MVS Gopher Client -`-`-
- %COMMAND ===>_ZCMD
- +
- %Gopher server host name+(or IP address) %===>_GGHOST
- +
- %Initial path%===>^GGPATH
- %Port number %===>_GGPORT
- +
- +Note: You may specify a dash%-+as the Gopher server host name if
- you want to use your own private Gopher data without making
- a connection to a server. If you do, you must specify the
- name of your private Gopher menu in the initial path.
- This name must be UNQUOTED AND FULLY QUALIFIED.
- Alternatively, you may allocate your initial Gopher menu
- to file GGGOPHER.
-
- Any menu entries must also specify a dash in the host field;
- otherwise they will require server access, as usual.
-
- To use the REXX interface, you must allocate file GGEXEC to
- your library of Gopherable REXX execs.
-
- +Press!END+key to leave this menu.
- )INIT
- &ZCMD = &Z
- IF (&GGPORT = &Z) &GGPORT = 70
- )PROC
- IF (&ZCMD ^= &Z) .MSG = ISPZ001
- VER (&GGHOST,NB)
- VER (&GGPORT,NUM)
- VPUT (GGHOST GGPATH GGPORT) PROFILE
- )END
- ./ ADD NAME=GGMDIR,SSI=01020021
- )ATTR
- /* /*
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 /*
- /* /*
- /* This software is provided on an "AS IS" basis. All warranties, /*
- /* including the implied warranties of merchantability and fitness, /*
- /* are expressly denied. /*
- /* /*
- /* Provided this copyright notice is included, this software may /*
- /* be freely distributed and not offered for sale. /*
- /* /*
- /* Changes or modifications may be made and used only by the maker /*
- /* of same, and not further distributed. Such modifications should /*
- /* be mailed to the author for consideration for addition to the /*
- /* software and incorporation in subsequent releases. /*
- /* /*
- ~ TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)
- ^ TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)
- ! TYPE(OUTPUT) INTENS(LOW) CAPS(OFF) JUST(RIGHT) COLOR(YELLOW)
- # TYPE(OUTPUT) INTENS(LOW) CAPS(OFF) JUST(RIGHT) COLOR(BLUE)
- @ TYPE(OUTPUT) INTENS(HIGH) CAPS(OFF) JUST(RIGHT) COLOR(PINK)
- ? TYPE(OUTPUT) INTENS(LOW) CAPS(OFF) JUST(LEFT) COLOR(TURQ) PAD('.')
- | AREA(DYNAMIC) EXTEND(ON) SCROLL(ON)
- \ AREA(DYNAMIC) EXTEND(OFF) SCROLL(OFF)
- 01 TYPE(DATAOUT) INTENS(LOW)
- 02 TYPE(DATAOUT) INTENS(HIGH)
- 03 TYPE(DATAIN) INTENS(LOW)
- 04 TYPE(DATAIN) INTENS(HIGH)
- 05 TYPE(DATAOUT) COLOR(GREEN)
- 06 TYPE(DATAOUT) COLOR(PINK)
- 07 TYPE(DATAOUT) COLOR(RED)
- 08 TYPE(DATAOUT) COLOR(TURQ)
- 09 TYPE(DATAOUT) COLOR(YELLOW)
- 0A TYPE(DATAIN) COLOR(BLUE)
- 0B TYPE(DATAIN) COLOR(PINK)
- 0C TYPE(DATAIN) COLOR(TURQ)
- 0D TYPE(DATAIN) COLOR(WHITE)
- 0E TYPE(DATAIN) COLOR(YELLOW)
- )BODY EXPAND(``)
- %&GGGHEAD
- %COMMAND ===>~GGGCMD %SCROLL ===>^GAMT+
- +
- +%S+Select%Q+Query%E+Extract
- -------------------------------------------------------------------------------
- |GGGDYNA |
- )INIT
- IF (&GAMT = &Z) &GAMT = CSR
- )PROC
- &GGGLVL = LVLINE(GGGDYNA)
- VPUT (GAMT) PROFILE
- )END
- ./ ADD NAME=GGMLCONN,SSI=01000059
- )ATTR
- /* /*
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 /*
- /* /*
- /* This software is provided on an "AS IS" basis. All warranties, /*
- /* including the implied warranties of merchantability and fitness, /*
- /* are expressly denied. /*
- /* /*
- /* Provided this copyright notice is included, this software may /*
- /* be freely distributed and not offered for sale. /*
- /* /*
- /* Changes or modifications may be made and used only by the maker /*
- /* of same, and not further distributed. Such modifications should /*
- /* be mailed to the author for consideration for addition to the /*
- /* software and incorporation in subsequent releases. /*
- /* /*
- ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)
- @ TYPE(TEXT) INTENS(HIGH) COLOR(PINK)
- # TYPE(TEXT) INTENS(LOW) COLOR(TURQ)
- \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)
- ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)
- $ TYPE(TEXT) INTENS(LOW) COLOR(GREEN)
- ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)
- )BODY EXPAND(``)
- %-`-`- MVS Gopher Server Connection -`-`-
- +
- + Client name: &GGCLIENT Client IP address: &GGCLIEIP
- +
- +
- + Connection is in progress for Gopher server at:
- &GGSERVER (&GGSERVIP)
- +
- +
- % Please wait.
- +
- +
- )INIT
- )PROC
- )END
- ./ ADD NAME=GGMLDISC,SSI=01000024
- )ATTR
- /* /*
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 /*
- /* /*
- /* This software is provided on an "AS IS" basis. All warranties, /*
- /* including the implied warranties of merchantability and fitness, /*
- /* are expressly denied. /*
- /* /*
- /* Provided this copyright notice is included, this software may /*
- /* be freely distributed and not offered for sale. /*
- /* /*
- /* Changes or modifications may be made and used only by the maker /*
- /* of same, and not further distributed. Such modifications should /*
- /* be mailed to the author for consideration for addition to the /*
- /* software and incorporation in subsequent releases. /*
- /* /*
- ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)
- @ TYPE(TEXT) INTENS(HIGH) COLOR(PINK)
- # TYPE(TEXT) INTENS(LOW) COLOR(TURQ)
- \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)
- ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)
- $ TYPE(TEXT) INTENS(LOW) COLOR(GREEN)
- ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)
- )BODY EXPAND(``)
- %-`-`- MVS Gopher Server Connection -`-`-
- +
- +
- + Disconnection is in progress from the Gopher server at:
- &GGSOLDER (&GGSOLDIP)
- +
- +
- % Please wait.
- +
- +
- )INIT
- )PROC
- )END
- ./ ADD NAME=GGMLEXN2,SSI=01000018
- )ATTR
- /* /*
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 /*
- /* /*
- /* This software is provided on an "AS IS" basis. All warranties, /*
- /* including the implied warranties of merchantability and fitness, /*
- /* are expressly denied. /*
- /* /*
- /* Provided this copyright notice is included, this software may /*
- /* be freely distributed and not offered for sale. /*
- /* /*
- /* Changes or modifications may be made and used only by the maker /*
- /* of same, and not further distributed. Such modifications should /*
- /* be mailed to the author for consideration for addition to the /*
- /* software and incorporation in subsequent releases. /*
- /* /*
- ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)
- @ TYPE(TEXT) INTENS(HIGH) COLOR(PINK)
- \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)
- ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)
- $ TYPE(TEXT) INTENS(LOW) COLOR(GREEN)
- ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)
- )BODY EXPAND(``)
- %-`-`- MVS Gopher Server Connection -`-`-
- +
- +Description: &GGTSUBJ
- +
- +Extracting to: &GGEXDSN
- +&MEMSTUFF
- +
- % Please wait.
- +
- )INIT
- IF (&GGEXMEM = &Z) &MEMSTUFF = &Z
- ELSE &MEMSTUFF = 'Member: &GGEXMEM'
- )PROC
- )END
- ./ ADD NAME=GGMLRCON,SSI=01000048
- )ATTR
- /* /*
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 /*
- /* /*
- /* This software is provided on an "AS IS" basis. All warranties, /*
- /* including the implied warranties of merchantability and fitness, /*
- /* are expressly denied. /*
- /* /*
- /* Provided this copyright notice is included, this software may /*
- /* be freely distributed and not offered for sale. /*
- /* /*
- /* Changes or modifications may be made and used only by the maker /*
- /* of same, and not further distributed. Such modifications should /*
- /* be mailed to the author for consideration for addition to the /*
- /* software and incorporation in subsequent releases. /*
- /* /*
- ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)
- @ TYPE(TEXT) INTENS(HIGH) COLOR(PINK)
- # TYPE(TEXT) INTENS(LOW) COLOR(TURQ)
- \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)
- ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)
- $ TYPE(TEXT) INTENS(LOW) COLOR(GREEN)
- ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)
- )BODY EXPAND(``)
- %-`-`- MVS Gopher Server Connection -`-`-
- +
- +Connection has apparently been lost to the Gopher server at:
- &GGSERVER (&GGSERVIP)
- +
- +Reconnection to the server is in progress.
- +
- % Please wait.
- +
- +
- )INIT
- )PROC
- )END
- ./ ADD NAME=GGMPCSO,SSI=01000011
- )ATTR
- /* /*
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 /*
- /* /*
- /* This software is provided on an "AS IS" basis. All warranties, /*
- /* including the implied warranties of merchantability and fitness, /*
- /* are expressly denied. /*
- /* /*
- /* Provided this copyright notice is included, this software may /*
- /* be freely distributed and not offered for sale. /*
- /* /*
- /* Changes or modifications may be made and used only by the maker /*
- /* of same, and not further distributed. Such modifications should /*
- /* be mailed to the author for consideration for addition to the /*
- /* software and incorporation in subsequent releases. /*
- /* /*
- ^ TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)
- )BODY WINDOW(58,10)
- +
- %Command ===>^ZCMD
- +
- +Enter name to search for:
- +
- %===>^GGCSOQ
-
- +Press%ENTER+to submit search request.
- +Press%&END (END)+to cancel the request.
- +
- )INIT
- &ZWINTTL = 'CSO Nameserver User Name Search'
- &END = PFK(END)
- .CURSOR = GGCSOQ
- )PROC
- IF (&ZCMD ^= &Z) .MSG = ISPZ001
- VER (&GGCSOQ,NB)
- VPUT (GGCSOQ) PROFILE
- )END
- ./ ADD NAME=GGMPEXDS,SSI=01000044
- )ATTR
- /* /*
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 /*
- /* /*
- /* This software is provided on an "AS IS" basis. All warranties, /*
- /* including the implied warranties of merchantability and fitness, /*
- /* are expressly denied. /*
- /* /*
- /* Provided this copyright notice is included, this software may /*
- /* be freely distributed and not offered for sale. /*
- /* /*
- /* Changes or modifications may be made and used only by the maker /*
- /* of same, and not further distributed. Such modifications should /*
- /* be mailed to the author for consideration for addition to the /*
- /* software and incorporation in subsequent releases. /*
- /* /*
- ^ TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)
- )BODY WINDOW(77,16)
- +
- %Command ===>^ZCMD
- +
- %&SUBJECT
- +
- +Save to data set ===>_GGEXDSN
- +Expand tab characters? ===>_Z +
-
- +(Note: Data set will be RECFM=VB, LRECL=259, BLKSIZE=6233.)
-
- +Append to end of data set? ===>_Z +
- +Blank line after separator? ===>_Z +
- +Separator line between items (append mode only...blank for none):
- +>^Z +<
-
- +Press%&END (END)+to cancel the extract request.
- )INIT
- .ZVARS = '(GGEXTAB GGEXAPP GGEXBLK GGEXSEP)'
- .CURSOR = GGEXDSN
- &ZWINTTL = 'Extract text'
- &SUBJECT = '&GGTSUBJ'
- &END = PFK(END)
- &ZCMD = &Z
- VGET (GGEXDSN GGEXTAB GGEXAPP GGEXBLK GGEXSEP) PROFILE
- &GGEXTAB = TRANS(&GGEXTAB Y,YES N,NO ' ',NO)
- &GGEXAPP = TRANS(&GGEXAPP Y,YES N,NO ' ',NO)
- &GGEXBLK = TRANS(&GGEXBLK Y,YES N,NO ' ',NO)
- )PROC
- IF (&ZCMD ^= &Z) .MSG = ISPZ001
- VER(&GGEXDSN,NB,DSNAME)
- &GGEXTAB = TRUNC(&GGEXTAB,1)
- VER(&GGEXTAB,NB,LIST,Y,N)
- &GGEXAPP = TRUNC(&GGEXAPP,1)
- VER(&GGEXAPP,NB,LIST,Y,N)
- &GGEXBLK = TRUNC(&GGEXBLK,1)
- VER(&GGEXBLK,NB,LIST,Y,N)
- VPUT (GGEXDSN GGEXTAB GGEXAPP GGEXBLK GGEXSEP) PROFILE
- )END
- ./ ADD NAME=GGMPEXNG,SSI=01000027
- )ATTR
- /* /*
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 /*
- /* /*
- /* This software is provided on an "AS IS" basis. All warranties, /*
- /* including the implied warranties of merchantability and fitness, /*
- /* are expressly denied. /*
- /* /*
- /* Provided this copyright notice is included, this software may /*
- /* be freely distributed and not offered for sale. /*
- /* /*
- /* Changes or modifications may be made and used only by the maker /*
- /* of same, and not further distributed. Such modifications should /*
- /* be mailed to the author for consideration for addition to the /*
- /* software and incorporation in subsequent releases. /*
- /* /*
- ^ TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)
- )BODY WINDOW(77,14)
- +
- %Command ===>^ZCMD
- +
- +Save to data set ===>_GGEXDSN
-
- +(Note: Data set will be RECFM=VB, LRECL=259, BLKSIZE=6233.)
-
- +Append to end of data set? ===>_Z +
- +Blank line after separator? ===>_Z +
- +Separator line between items (append mode only...blank for none):
- +>^Z +<
-
- +Press%&END (END)+to cancel the extract request.
- )INIT
- .ZVARS = '(GGEXAPP GGEXBLK GGEXSEP)'
- .CURSOR = GGEXDSN
- &ZWINTTL = 'Extract item listing'
- &END = PFK(END)
- &ZCMD = &Z
- VGET (GGEXDSN GGEXAPP GGEXBLK GGEXSEP) PROFILE
- &GGEXAPP = TRANS(&GGEXAPP Y,YES N,NO ' ',NO)
- &GGEXBLK = TRANS(&GGEXBLK Y,YES N,NO ' ',NO)
- )PROC
- IF (&ZCMD ^= &Z) .MSG = ISPZ001
- VER(&GGEXDSN,NB,DSNAME)
- &GGEXAPP = TRUNC(&GGEXAPP,1)
- VER(&GGEXAPP,NB,LIST,Y,N)
- &GGEXBLK = TRUNC(&GGEXBLK,1)
- VER(&GGEXBLK,NB,LIST,Y,N)
- VPUT (GGEXDSN GGEXAPP GGEXBLK GGEXSEP) PROFILE
- )END
- ./ ADD NAME=GGMPEXNP,SSI=01000026
- )ATTR
- /* /*
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 /*
- /* /*
- /* This software is provided on an "AS IS" basis. All warranties, /*
- /* including the implied warranties of merchantability and fitness, /*
- /* are expressly denied. /*
- /* /*
- /* Provided this copyright notice is included, this software may /*
- /* be freely distributed and not offered for sale. /*
- /* /*
- /* Changes or modifications may be made and used only by the maker /*
- /* of same, and not further distributed. Such modifications should /*
- /* be mailed to the author for consideration for addition to the /*
- /* software and incorporation in subsequent releases. /*
- /* /*
- ^ TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)
- )BODY EXPAND(``) WINDOW(77,14)
- +
- %Command ===>^ZCMD
- +
- +Data set name%===>_GGEXPDS
- +Member prefix%===>_GGEXPMP + (item number appended - default is%#+)
-
- +Note: The dataset must be a PDS (old or new) with RECFM=VB and LRECL=259.
-
- +Expand tab characters? %===>_Z +
-
- +From item number%===>_GGEXAN1 + (blank for first item in table)
- +To item number%===>_GGEXAN2 + (blank for last item in table)
-
- +Press%&END (END)+to cancel the extract request.
- )INIT
- .ZVARS = '(GGEXTAB)'
- .CURSOR = ZCMD
- &ZWINTTL = 'Log text of items to PDS members'
- &END = PFK(END)
- &ZCMD = &Z
- VGET (GGEXPDS GGEXPMP GGEXTAB) PROFILE
- &GGEXTAB = TRANS(&GGEXTAB Y,YES N,NO ' ',NO)
- IF (&GGEXPMP = &Z) &GGEXPMP = '#'
- &GGEXAN1 = &Z
- &GGEXAN2 = &Z
- )PROC
- IF (&ZCMD ^= &Z) .MSG = ISPZ001
- &GGEXTAB = TRUNC(&GGEXTAB,1)
- VER(&GGEXTAB,NB,LIST,Y,N)
- VER(&GGEXPDS,NB,DSNAME)
- &TEMP1 = TRUNC(&GGEXPDS,1)
- &TEMP2 = .TRAIL
- IF (&TEMP1 = '''')
- &GGEXDSN = TRUNC(&TEMP2,'''')
- ELSE
- &GGEXDSN = '&ZPREFIX..&GGEXPDS'
- VER(&GGEXPMP,NB,NAME)
- VER(&GGEXAN1,NUM)
- VER(&GGEXAN2,NUM)
- VPUT (GGEXPDS GGEXPMP GGEXTAB) PROFILE
- )END
- ./ ADD NAME=GGMPEXNS,SSI=01000057
- )ATTR
- /* /*
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 /*
- /* /*
- /* This software is provided on an "AS IS" basis. All warranties, /*
- /* including the implied warranties of merchantability and fitness, /*
- /* are expressly denied. /*
- /* /*
- /* Provided this copyright notice is included, this software may /*
- /* be freely distributed and not offered for sale. /*
- /* /*
- /* Changes or modifications may be made and used only by the maker /*
- /* of same, and not further distributed. Such modifications should /*
- /* be mailed to the author for consideration for addition to the /*
- /* software and incorporation in subsequent releases. /*
- /* /*
- ^ TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)
- )BODY EXPAND(``) WINDOW(77,17)
- +
- %Command ===>^ZCMD
- +
- +Data set name%===>_GGEXSEQ
- +(Note: Data set will be RECFM=VB, LRECL=259, BLKSIZE=6233.)
- +
- +Expand tab characters? %===>_Z +
- +
- +Append to end of data set? %===>_Z +
- +Blank line after separator? %===>_Z +
- +Separator line before each item (leave blank for none):
- +>^Z +<
-
- +From item number%===>_GGEXAN1 + (blank for first item in table)
- +To item number%===>_GGEXAN2 + (blank for last item in table)
-
- +Press%&END (END)+to cancel the extract request.
- )INIT
- .ZVARS = '(GGEXTAB GGEXAPP GGEXBLK GGEXSEP)'
- .CURSOR = ZCMD
- &ZWINTTL = 'Log text of items to sequential file'
- &END = PFK(END)
- &ZCMD = &Z
- VGET (GGEXSEQ GGEXTAB GGEXAPP GGEXBLK GGEXSEP) PROFILE
- &GGEXTAB = TRANS(&GGEXTAB Y,YES N,NO ' ',NO)
- &GGEXAPP = TRANS(&GGEXAPP Y,YES N,NO ' ',NO)
- &GGEXBLK = TRANS(&GGEXBLK Y,YES N,NO ' ',NO)
- &GGEXAN1 = &Z
- &GGEXAN2 = &Z
- )PROC
- IF (&ZCMD ^= &Z) .MSG = ISPZ001
- VER(&GGEXSEQ,NB,DSNAME)
- &GGEXDSN = &GGEXSEQ
- &GGEXTAB = TRUNC(&GGEXTAB,1)
- VER(&GGEXTAB,NB,LIST,Y,N)
- &GGEXAPP = TRUNC(&GGEXAPP,1)
- VER(&GGEXAPP,NB,LIST,Y,N)
- &GGEXBLK = TRUNC(&GGEXBLK,1)
- VER(&GGEXBLK,NB,LIST,Y,N)
- VER(&GGEXAN1,NUM)
- VER(&GGEXAN2,NUM)
- VPUT (GGEXSEQ GGEXTAB GGEXAPP GGEXBLK GGEXSEP) PROFILE
- )END
- ./ ADD NAME=GGMPEXNT,SSI=01000035
- )ATTR
- /* /*
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 /*
- /* /*
- /* This software is provided on an "AS IS" basis. All warranties, /*
- /* including the implied warranties of merchantability and fitness, /*
- /* are expressly denied. /*
- /* /*
- /* Provided this copyright notice is included, this software may /*
- /* be freely distributed and not offered for sale. /*
- /* /*
- /* Changes or modifications may be made and used only by the maker /*
- /* of same, and not further distributed. Such modifications should /*
- /* be mailed to the author for consideration for addition to the /*
- /* software and incorporation in subsequent releases. /*
- /* /*
- ^ TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)
- )BODY WINDOW(77,10)
- +
- %Command ===>^ZCMD
- +
- +Move cursor to choice (or type%S+next to choice) and press%ENTER+to select:
- +
- _A%1+- List%titles+of items in table
- _B%2+- Log %text +of items to%sequential file+
- _C%3+- Log %text +of items to%members of PDS+
- +
- +Press%&END (END)+to cancel the extract request.
- )INIT
- .CURSOR = ZCMD
- &ZWINTTL = 'Extract Gopher items - titles or text'
- &END = PFK(END)
- &ZCMD = &Z
- &A = &Z
- &B = &Z
- &C = &Z
- )PROC
- VER(&ZCMD,LIST,1,2,3)
- IF (&ZCMD ^= &Z)
- &GGCHOICE = TRANS(&ZCMD 1 1 2 2 3 3 * ?)
- ELSE
- &TEMP = '&A/&B/&C'
- IF (&TEMP = '//')
- &GGCHOICE = TRANS(.CURSOR A 1 B 2 C 3 * ?)
- ELSE
- &GGCHOICE = TRANS(&TEMP 'S//' 1
- '1//' 1
- '/S/' 2
- '/2/' 2
- '//S' 3
- '//3' 3
- * ?
- )
- )END
- ./ ADD NAME=GGMPEXN1,SSI=01000007
- )ATTR
- /* /*
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 /*
- /* /*
- /* This software is provided on an "AS IS" basis. All warranties, /*
- /* including the implied warranties of merchantability and fitness, /*
- /* are expressly denied. /*
- /* /*
- /* Provided this copyright notice is included, this software may /*
- /* be freely distributed and not offered for sale. /*
- /* /*
- /* Changes or modifications may be made and used only by the maker /*
- /* of same, and not further distributed. Such modifications should /*
- /* be mailed to the author for consideration for addition to the /*
- /* software and incorporation in subsequent releases. /*
- /* /*
- ^ TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)
- )BODY WINDOW(77,14)
- +
- %Command ===>^ZCMD
- +
- +Save to data set ===>_GGEXDSN
-
- +(Note: Data set will be RECFM=VB, LRECL=259, BLKSIZE=6233.)
-
- +Append to end of data set? ===>_Z +
- +Blank line after separator? ===>_Z +
- +Separator line between items (append mode only...blank for none):
- +>^Z +<
-
- +Press%&END (END)+to cancel the extract request.
- )INIT
- .ZVARS = '(GGEXAPP GGEXBLK GGEXSEP)'
- .CURSOR = GGEXDSN
- &ZWINTTL = 'Extract Gopher item listing'
- &END = PFK(END)
- &ZCMD = &Z
- VGET (GGEXDSN GGEXAPP GGEXBLK GGEXSEP) PROFILE
- &GGEXAPP = TRANS(&GGEXAPP Y,YES N,NO ' ',NO)
- &GGEXBLK = TRANS(&GGEXBLK Y,YES N,NO ' ',NO)
- )PROC
- IF (&ZCMD ^= &Z) .MSG = ISPZ001
- VER(&GGEXDSN,NB,DSNAME)
- &GGEXAPP = TRUNC(&GGEXAPP,1)
- VER(&GGEXAPP,NB,LIST,Y,N)
- &GGEXBLK = TRUNC(&GGEXBLK,1)
- VER(&GGEXBLK,NB,LIST,Y,N)
- VPUT (GGEXDSN GGEXAPP GGEXBLK GGEXSEP) PROFILE
- )END
- ./ ADD NAME=GGMPEXOW,SSI=01000030
- )ATTR
- /* /*
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 /*
- /* /*
- /* This software is provided on an "AS IS" basis. All warranties, /*
- /* including the implied warranties of merchantability and fitness, /*
- /* are expressly denied. /*
- /* /*
- /* Provided this copyright notice is included, this software may /*
- /* be freely distributed and not offered for sale. /*
- /* /*
- /* Changes or modifications may be made and used only by the maker /*
- /* of same, and not further distributed. Such modifications should /*
- /* be mailed to the author for consideration for addition to the /*
- /* software and incorporation in subsequent releases. /*
- /* /*
- ^ TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)
- )BODY WINDOW(58,10)
- +
- %Command ===>^ZCMD
- +
- +Dataset already exists:
- +
- %&GGEXDSN
- +
- +Press%ENTER+to%&ACTION
- +Press%&END (END)+to cancel the request.
- +
- )INIT
- .ALARM = YES
- &ZWINTTL = 'Extract To Existing Data Set'
- &END = PFK(END)
- &APP = TRUNC(&GGEXAPP,1)
- IF (&APP = Y) &ACTION = 'append to the end of the data set.'
- ELSE &ACTION = 'overwrite the current data set.'
- )PROC
- IF (&ZCMD ^= &Z) .MSG = ISPZ001
- )END
- ./ ADD NAME=GGMPEXPW,SSI=01000053
- )ATTR
- /* /*
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 /*
- /* /*
- /* This software is provided on an "AS IS" basis. All warranties, /*
- /* including the implied warranties of merchantability and fitness, /*
- /* are expressly denied. /*
- /* /*
- /* Provided this copyright notice is included, this software may /*
- /* be freely distributed and not offered for sale. /*
- /* /*
- /* Changes or modifications may be made and used only by the maker /*
- /* of same, and not further distributed. Such modifications should /*
- /* be mailed to the author for consideration for addition to the /*
- /* software and incorporation in subsequent releases. /*
- /* /*
- ^ TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)
- )BODY WINDOW(58,13)
- +
- %Command ===>^ZCMD
- +
- +Paritioned dataset already exists:
- +
- %&GGEXDSN
- +
- +If member names are generated that match existing members
- +of this PDS, they will be%overwritten.+
- +
- +Press%ENTER+to proceed to use this PDS.
- +Press%&END (END)+to cancel the request.
- +
- )INIT
- .ALARM = YES
- &ZWINTTL = 'Extract To Members of Existing PDS'
- &END = PFK(END)
- )PROC
- IF (&ZCMD ^= &Z) .MSG = ISPZ001
- )END
- ./ ADD NAME=GGMPWAIS,SSI=01020012
- )ATTR
- /* /*
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 /*
- /* /*
- /* This software is provided on an "AS IS" basis. All warranties, /*
- /* including the implied warranties of merchantability and fitness, /*
- /* are expressly denied. /*
- /* /*
- /* Provided this copyright notice is included, this software may /*
- /* be freely distributed and not offered for sale. /*
- /* /*
- /* Changes or modifications may be made and used only by the maker /*
- /* of same, and not further distributed. Such modifications should /*
- /* be mailed to the author for consideration for addition to the /*
- /* software and incorporation in subsequent releases. /*
- /* /*
- ^ TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)
- )BODY WINDOW(58,10)
- +
- %Command ===>^ZCMD
- +
- +Enter index search query:
- +
- %===>^GGWAISQ
-
- +Press%ENTER+to submit search request.
- +Press%&END (END)+to cancel the request.
- +
- )INIT
- &ZWINTTL = 'GOPHER Full Text Index Search'
- &END = PFK(END)
- .CURSOR = GGWAISQ
- )PROC
- IF (&ZCMD ^= &Z) .MSG = ISPZ001
- VER (&GGWAISQ,NB)
- VPUT (GGWAISQ) PROFILE
- )END
- ./ ADD NAME=GGMPWHOI,SSI=01000019
- )ATTR
- /* /*
- /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992 /*
- /* /*
- /* This software is provided on an "AS IS" basis. All warranties, /*
- /* including the implied warranties of merchantability and fitness, /*
- /* are expressly denied. /*
- /* /*
- /* Provided this copyright notice is included, this software may /*
- /* be freely distributed and not offered for sale. /*
- /* /*
- /* Changes or modifications may be made and used only by the maker /*
- /* of same, and not further distributed. Such modifications should /*
- /* be mailed to the author for consideration for addition to the /*
- /* software and incorporation in subsequent releases. /*
- /* /*
- ^ TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)
- )BODY WINDOW(58,10)
- +
- %Command ===>^ZCMD
- +
- +Enter name to search for:
- +
- %===>^GGWHOISQ
-
- +Press%ENTER+to submit search request.
- +Press%&END (END)+to cancel the request.
- +
- )INIT
- &ZWINTTL = 'WHOIS/FINGER User Name Search'
- &END = PFK(END)
- .CURSOR = GGWHOISQ
- )PROC
- IF (&ZCMD ^= &Z) .MSG = ISPZ001
- VER (&GGWHOISQ,NB)
- VPUT (GGWHOISQ) PROFILE
- )END
- ./ ENDUP
- ?!
-